Changeset da1bafb in mainline for kernel/generic/src/ipc/ipc.c


Ignore:
Timestamp:
2010-05-24T18:57:31Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0095368
Parents:
666f492
Message:

major code revision

  • replace spinlocks taken with interrupts disabled with irq_spinlocks
  • change spacing (not indendation) to be tab-size independent
  • use unsigned integer types where appropriate (especially bit flags)
  • visual separation
  • remove argument names in function prototypes
  • string changes
  • correct some formating directives
  • replace various cryptic single-character variables (t, a, m, c, b, etc.) with proper identifiers (thread, task, timeout, as, itm, itc, etc.)
  • unify some assembler constructs
  • unused page table levels are now optimized out in compile time
  • replace several ints (with boolean semantics) with bools
  • use specifically sized types instead of generic types where appropriate (size_t, uint32_t, btree_key_t)
  • improve comments
  • split asserts with conjuction into multiple independent asserts
File:
1 edited

Legend:

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

    r666f492 rda1bafb  
    6666/** Initialize a call structure.
    6767 *
    68  * @param call          Call structure to be initialized.
     68 * @param call Call structure to be initialized.
     69 *
    6970 */
    7071static void _ipc_call_init(call_t *call)
     
    7778
    7879/** Allocate and initialize a call structure.
    79  * 
     80 *
    8081 * The call is initialized, so that the reply will be directed to
    8182 * TASK->answerbox.
    8283 *
    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  */
    88 call_t *ipc_call_alloc(int flags)
    89 {
    90         call_t *call;
    91 
    92         call = slab_alloc(ipc_call_slab, flags);
     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 */
     90call_t *ipc_call_alloc(unsigned int flags)
     91{
     92        call_t *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.
     101 * @param call Call structure to be freed.
     102 *
    102103 */
    103104void ipc_call_free(call_t *call)
     
    111112/** Initialize an answerbox structure.
    112113 *
    113  * @param box           Answerbox structure to be initialized.
    114  * @param task          Task to which the answerbox belongs.
     114 * @param box  Answerbox structure to be initialized.
     115 * @param task Task to which the answerbox belongs.
     116 *
    115117 */
    116118void ipc_answerbox_init(answerbox_t *box, task_t *task)
    117119{
    118         spinlock_initialize(&box->lock, "ipc_box_lock");
    119         spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
     120        irq_spinlock_initialize(&box->lock, "ipc.box.lock");
     121        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    120122        waitq_initialize(&box->wq);
    121123        link_initialize(&box->sync_box_link);
     
    131133/** Connect a phone to an answerbox.
    132134 *
    133  * @param phone         Initialized phone structure.
    134  * @param box           Initialized answerbox structure.
     135 * @param phone Initialized phone structure.
     136 * @param box   Initialized answerbox structure.
     137 *
    135138 */
    136139void ipc_phone_connect(phone_t *phone, answerbox_t *box)
    137140{
    138141        mutex_lock(&phone->lock);
    139 
     142       
    140143        phone->state = IPC_PHONE_CONNECTED;
    141144        phone->callee = box;
    142 
    143         spinlock_lock(&box->lock);
     145       
     146        irq_spinlock_lock(&box->lock, true);
    144147        list_append(&phone->link, &box->connected_phones);
    145         spinlock_unlock(&box->lock);
    146 
     148        irq_spinlock_unlock(&box->lock, true);
     149       
    147150        mutex_unlock(&phone->lock);
    148151}
     
    150153/** Initialize a phone structure.
    151154 *
    152  * @param phone         Phone structure to be initialized.
     155 * @param phone Phone structure to be initialized.
     156 *
    153157 */
    154158void ipc_phone_init(phone_t *phone)
     
    162166/** Helper function to facilitate synchronous calls.
    163167 *
    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.
     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 *
    168173 */
    169174int ipc_call_sync(phone_t *phone, call_t *request)
    170175{
    171         answerbox_t *sync_box;
    172         ipl_t ipl;
    173 
    174         sync_box = slab_alloc(ipc_answerbox_slab, 0);
     176        answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
    175177        ipc_answerbox_init(sync_box, TASK);
    176 
     178       
    177179        /*
    178180         * Put the answerbox on the TASK's list of synchronous answerboxes so
    179181         * that it can be cleaned up if the call is interrupted.
    180182         */
    181         ipl = interrupts_disable();
    182         spinlock_lock(&TASK->lock);
     183        irq_spinlock_lock(&TASK->lock, true);
    183184        list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
    184         spinlock_unlock(&TASK->lock);
    185         interrupts_restore(ipl);
    186 
     185        irq_spinlock_unlock(&TASK->lock, true);
     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         (void) interrupts_disable();
    202         spinlock_lock(&TASK->lock);
     201        irq_spinlock_lock(&TASK->lock, true);
    203202        list_remove(&sync_box->sync_box_link);
    204         spinlock_unlock(&TASK->lock);
    205         interrupts_restore(ipl);
    206 
     203        irq_spinlock_unlock(&TASK->lock, true);
     204       
    207205        slab_free(ipc_answerbox_slab, sync_box);
    208206        return EOK;
     
    211209/** Answer a message which was not dispatched and is not listed in any queue.
    212210 *
    213  * @param call          Call structure to be answered.
    214  * @param selflocked    If true, then TASK->answebox is locked.
     211 * @param call       Call structure to be answered.
     212 * @param selflocked If true, then TASK->answebox is locked.
     213 *
    215214 */
    216215static void _ipc_answer_free_call(call_t *call, bool selflocked)
     
    218217        answerbox_t *callerbox = call->callerbox;
    219218        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    220         ipl_t ipl;
    221 
     219       
    222220        /* Count sent answer */
    223         ipl = interrupts_disable();
    224         spinlock_lock(&TASK->lock);
     221        irq_spinlock_lock(&TASK->lock, true);
    225222        TASK->ipc_info.answer_sent++;
    226         spinlock_unlock(&TASK->lock);
    227         interrupts_restore(ipl);
    228 
     223        irq_spinlock_unlock(&TASK->lock, true);
     224       
    229225        call->flags |= IPC_CALL_ANSWERED;
    230 
     226       
    231227        if (call->flags & IPC_CALL_FORWARDED) {
    232228                if (call->caller_phone) {
     
    235231                }
    236232        }
    237 
     233       
    238234        if (do_lock)
    239                 spinlock_lock(&callerbox->lock);
     235                irq_spinlock_lock(&callerbox->lock, true);
     236       
    240237        list_append(&call->link, &callerbox->answers);
     238       
    241239        if (do_lock)
    242                 spinlock_unlock(&callerbox->lock);
     240                irq_spinlock_unlock(&callerbox->lock, true);
     241       
    243242        waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
    244243}
     
    246245/** Answer a message which is in a callee queue.
    247246 *
    248  * @param box           Answerbox that is answering the message.
    249  * @param call          Modified request that is being sent back.
     247 * @param box  Answerbox that is answering the message.
     248 * @param call Modified request that is being sent back.
     249 *
    250250 */
    251251void ipc_answer(answerbox_t *box, call_t *call)
    252252{
    253253        /* Remove from active box */
    254         spinlock_lock(&box->lock);
     254        irq_spinlock_lock(&box->lock, true);
    255255        list_remove(&call->link);
    256         spinlock_unlock(&box->lock);
     256        irq_spinlock_unlock(&box->lock, true);
     257       
    257258        /* Send back answer */
    258259        _ipc_answer_free_call(call, false);
     
    264265 * message and sending it as a normal answer.
    265266 *
    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.
     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 *
    269271 */
    270272void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err)
     
    278280/** Unsafe unchecking version of ipc_call.
    279281 *
    280  * @param phone         Phone structure the call comes from.
    281  * @param box           Destination answerbox structure.
    282  * @param call          Call structure with request.
     282 * @param phone Phone structure the call comes from.
     283 * @param box   Destination answerbox structure.
     284 * @param call  Call structure with request.
     285 *
    283286 */
    284287static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
    285288{
    286         ipl_t ipl;
    287 
    288289        /* Count sent ipc call */
    289         ipl = interrupts_disable();
    290         spinlock_lock(&TASK->lock);
     290        irq_spinlock_lock(&TASK->lock, true);
    291291        TASK->ipc_info.call_sent++;
    292         spinlock_unlock(&TASK->lock);
    293         interrupts_restore(ipl);
    294 
     292        irq_spinlock_unlock(&TASK->lock, true);
     293       
    295294        if (!(call->flags & IPC_CALL_FORWARDED)) {
    296295                atomic_inc(&phone->active_calls);
    297296                call->data.phone = phone;
    298297        }
    299 
    300         spinlock_lock(&box->lock);
     298       
     299        irq_spinlock_lock(&box->lock, true);
    301300        list_append(&call->link, &box->calls);
    302         spinlock_unlock(&box->lock);
     301        irq_spinlock_unlock(&box->lock, true);
     302       
    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.
     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 *
    313314 */
    314315int ipc_call(phone_t *phone, call_t *call)
    315316{
    316         answerbox_t *box;
    317 
    318317        mutex_lock(&phone->lock);
    319318        if (phone->state != IPC_PHONE_CONNECTED) {
     
    328327                                ipc_backsend_err(phone, call, ENOENT);
    329328                }
     329               
    330330                return ENOENT;
    331331        }
    332         box = phone->callee;
     332       
     333        answerbox_t *box = phone->callee;
    333334        _ipc_call(phone, box, call);
    334335       
     
    342343 * lazily later.
    343344 *
    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.
     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 *
    348350 */
    349351int ipc_phone_hangup(phone_t *phone)
    350352{
    351         answerbox_t *box;
    352         call_t *call;
    353        
    354353        mutex_lock(&phone->lock);
    355354        if (phone->state == IPC_PHONE_FREE ||
     
    359358                return -1;
    360359        }
    361         box = phone->callee;
     360       
     361        answerbox_t *box = phone->callee;
    362362        if (phone->state != IPC_PHONE_SLAMMED) {
    363363                /* Remove myself from answerbox */
    364                 spinlock_lock(&box->lock);
     364                irq_spinlock_lock(&box->lock, true);
    365365                list_remove(&phone->link);
    366                 spinlock_unlock(&box->lock);
    367 
    368                 call = ipc_call_alloc(0);
     366                irq_spinlock_unlock(&box->lock, true);
     367               
     368                call_t *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              Return 0 if forwarding succeeded or an error code if
    388  *                      there was 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 0 if forwarding succeeded or an error code if
     388 *         there was an 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 int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox, int mode)
    394 {
    395         ipl_t ipl;
    396 
     392 *
     393 */
     394int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox,
     395    unsigned int mode)
     396{
    397397        /* Count forwarded calls */
    398         ipl = interrupts_disable();
    399         spinlock_lock(&TASK->lock);
     398        irq_spinlock_lock(&TASK->lock, true);
    400399        TASK->ipc_info.forwarded++;
    401         spinlock_unlock(&TASK->lock);
    402         interrupts_restore(ipl);
    403 
    404         spinlock_lock(&oldbox->lock);
     400        irq_spinlock_pass(&TASK->lock, &oldbox->lock);
    405401        list_remove(&call->link);
    406         spinlock_unlock(&oldbox->lock);
    407 
     402        irq_spinlock_unlock(&oldbox->lock, true);
     403       
    408404        if (mode & IPC_FF_ROUTE_FROM_ME) {
    409405                if (!call->caller_phone)
     
    411407                call->data.phone = newphone;
    412408        }
    413 
     409       
    414410        return ipc_call(newphone, call);
    415411}
     
    418414/** Wait for a phone call.
    419415 *
    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  *
     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 *
    429426 * To distinguish between a call and an answer, have a look at call->flags.
    430  */
    431 call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags)
     427 *
     428 */
     429call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, unsigned int flags)
    432430{
    433431        call_t *request;
    434         ipl_t ipl;
    435432        uint64_t irq_cnt = 0;
    436433        uint64_t answer_cnt = 0;
    437434        uint64_t call_cnt = 0;
    438435        int rc;
    439 
     436       
    440437restart:
    441438        rc = waitq_sleep_timeout(&box->wq, usec, flags);
     
    443440                return NULL;
    444441       
    445         spinlock_lock(&box->lock);
     442        irq_spinlock_lock(&box->lock, true);
    446443        if (!list_empty(&box->irq_notifs)) {
    447444                /* Count recieved IRQ notification */
    448                 irq_cnt++;     
    449 
    450                 ipl = interrupts_disable();
    451                 spinlock_lock(&box->irq_lock);
    452 
     445                irq_cnt++;
     446               
     447                irq_spinlock_lock(&box->irq_lock, false);
     448               
    453449                request = list_get_instance(box->irq_notifs.next, call_t, link);
    454450                list_remove(&request->link);
    455 
    456                 spinlock_unlock(&box->irq_lock);
    457                 interrupts_restore(ipl);
     451               
     452                irq_spinlock_unlock(&box->irq_lock, false);
    458453        } else if (!list_empty(&box->answers)) {
    459454                /* Count recieved answer */
    460455                answer_cnt++;
    461 
     456               
    462457                /* Handle asynchronous answers */
    463458                request = list_get_instance(box->answers.next, call_t, link);
     
    467462                /* Count recieved call */
    468463                call_cnt++;
    469 
     464               
    470465                /* Handle requests */
    471466                request = list_get_instance(box->calls.next, call_t, link);
    472467                list_remove(&request->link);
     468               
    473469                /* Append request to dispatch queue */
    474470                list_append(&request->link, &box->dispatched_calls);
    475471        } else {
    476472                /* This can happen regularly after ipc_cleanup */
    477                 spinlock_unlock(&box->lock);
     473                irq_spinlock_unlock(&box->lock, true);
    478474                goto restart;
    479475        }
    480         spinlock_unlock(&box->lock);
    481        
    482         ipl = interrupts_disable();
    483         spinlock_lock(&TASK->lock);
     476       
     477        irq_spinlock_pass(&box->lock, &TASK->lock);
     478       
    484479        TASK->ipc_info.irq_notif_recieved += irq_cnt;
    485480        TASK->ipc_info.answer_recieved += answer_cnt;
    486481        TASK->ipc_info.call_recieved += call_cnt;
    487         spinlock_unlock(&TASK->lock);
    488         interrupts_restore(ipl);
    489 
     482       
     483        irq_spinlock_unlock(&TASK->lock, true);
     484       
    490485        return request;
    491486}
     
    493488/** Answer all calls from list with EHANGUP answer.
    494489 *
    495  * @param lst           Head of the list to be cleaned up.
     490 * @param lst Head of the list to be cleaned up.
     491 *
    496492 */
    497493void ipc_cleanup_call_list(link_t *lst)
    498494{
    499         call_t *call;
    500 
    501495        while (!list_empty(lst)) {
    502                 call = list_get_instance(lst->next, call_t, link);
     496                call_t *call = list_get_instance(lst->next, call_t, link);
    503497                if (call->buffer)
    504498                        free(call->buffer);
     499               
    505500                list_remove(&call->link);
    506 
     501               
    507502                IPC_SET_RETVAL(call->data, EHANGUP);
    508503                _ipc_answer_free_call(call, true);
     
    512507/** Disconnects all phones connected to an answerbox.
    513508 *
    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.
     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 *
    517513 */
    518514void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
     
    520516        phone_t *phone;
    521517        DEADLOCK_PROBE_INIT(p_phonelck);
    522         ipl_t ipl;
    523         call_t *call;
    524 
    525         call = notify_box ? ipc_call_alloc(0) : NULL;
    526 
     518       
     519        call_t *call = notify_box ? ipc_call_alloc(0) : NULL;
     520       
    527521        /* Disconnect all phones connected to our answerbox */
    528522restart_phones:
    529         ipl = interrupts_disable();
    530         spinlock_lock(&box->lock);
     523        irq_spinlock_lock(&box->lock, true);
    531524        while (!list_empty(&box->connected_phones)) {
    532525                phone = list_get_instance(box->connected_phones.next,
    533526                    phone_t, link);
    534527                if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
    535                         spinlock_unlock(&box->lock);
    536                         interrupts_restore(ipl);
     528                        irq_spinlock_unlock(&box->lock, true);
    537529                        DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
    538530                        goto restart_phones;
     
    541533                /* Disconnect phone */
    542534                ASSERT(phone->state == IPC_PHONE_CONNECTED);
    543 
     535               
    544536                list_remove(&phone->link);
    545537                phone->state = IPC_PHONE_SLAMMED;
    546 
     538               
    547539                if (notify_box) {
    548540                        mutex_unlock(&phone->lock);
    549                         spinlock_unlock(&box->lock);
    550                         interrupts_restore(ipl);
    551 
     541                        irq_spinlock_unlock(&box->lock, true);
     542                       
    552543                        /*
    553544                         * Send one message to the answerbox for each
     
    559550                        call->flags |= IPC_CALL_DISCARD_ANSWER;
    560551                        _ipc_call(phone, box, call);
    561 
     552                       
    562553                        /* Allocate another call in advance */
    563554                        call = ipc_call_alloc(0);
    564 
     555                       
    565556                        /* Must start again */
    566557                        goto restart_phones;
    567558                }
    568 
     559               
    569560                mutex_unlock(&phone->lock);
    570561        }
    571 
    572         spinlock_unlock(&box->lock);
    573         interrupts_restore(ipl);
    574 
     562       
     563        irq_spinlock_unlock(&box->lock, true);
     564       
    575565        /* Free unused call */
    576566        if (call)
     
    578568}
    579569
    580 /** Cleans up all IPC communication of the current task.
     570/** Clean up all IPC communication of the current task.
    581571 *
    582572 * Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
    583573 * have to change it as well if you want to cleanup other tasks than TASK.
     574 *
    584575 */
    585576void ipc_cleanup(void)
    586577{
    587         int i;
    588         call_t *call;
    589         ipl_t ipl;
    590 
    591578        /* Disconnect all our phones ('ipc_phone_hangup') */
     579        size_t i;
    592580        for (i = 0; i < IPC_MAX_PHONES; i++)
    593581                ipc_phone_hangup(&TASK->phones[i]);
    594 
     582       
    595583        /* Unsubscribe from any event notifications. */
    596584        event_cleanup_answerbox(&TASK->answerbox);
    597 
     585       
    598586        /* Disconnect all connected irqs */
    599587        ipc_irq_cleanup(&TASK->answerbox);
    600 
     588       
    601589        /* Disconnect all phones connected to our regular answerbox */
    602590        ipc_answerbox_slam_phones(&TASK->answerbox, false);
    603 
     591       
    604592#ifdef CONFIG_UDEBUG
    605593        /* Clean up kbox thread and communications */
    606594        ipc_kbox_cleanup();
    607595#endif
    608 
     596       
    609597        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    610         spinlock_lock(&TASK->answerbox.lock);
     598        irq_spinlock_lock(&TASK->answerbox.lock, true);
    611599        ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
    612600        ipc_cleanup_call_list(&TASK->answerbox.calls);
    613         spinlock_unlock(&TASK->answerbox.lock);
     601        irq_spinlock_unlock(&TASK->answerbox.lock, true);
    614602       
    615603        /* Wait for all answers to interrupted synchronous calls to arrive */
    616         ipl = interrupts_disable();
     604        ipl_t ipl = interrupts_disable();
    617605        while (!list_empty(&TASK->sync_box_head)) {
    618606                answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
    619607                    answerbox_t, sync_box_link);
    620 
     608               
    621609                list_remove(&box->sync_box_link);
    622                 call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
     610                call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    623611                    SYNCH_FLAGS_NONE);
    624612                ipc_call_free(call);
     
    626614        }
    627615        interrupts_restore(ipl);
    628 
     616       
    629617        /* Wait for all answers to asynchronous calls to arrive */
    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 */
     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                 */
    634624                for (i = 0; i < IPC_MAX_PHONES; i++) {
    635625                        if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
     
    639629                        }
    640630                       
    641                         /* Just for sure, we might have had some
    642                          * IPC_PHONE_CONNECTING phones */
     631                        /*
     632                         * Just for sure, we might have had some
     633                         * IPC_PHONE_CONNECTING phones
     634                         */
    643635                        if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
    644636                                ipc_phone_hangup(&TASK->phones[i]);
    645                         /* If the hangup succeeded, it has sent a HANGUP
     637                       
     638                        /*
     639                         * If the hangup succeeded, it has sent a HANGUP
    646640                         * message, the IPC is now in HUNGUP state, we
    647                          * wait for the reply to come */
     641                         * wait for the reply to come
     642                         */
    648643                       
    649644                        if (TASK->phones[i].state != IPC_PHONE_FREE)
    650645                                break;
    651646                }
    652                 /* Voila, got into cleanup */
     647               
     648                /* Got into cleanup */
    653649                if (i == IPC_MAX_PHONES)
    654650                        break;
    655651               
    656                 call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
     652                call_t *call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
    657653                    SYNCH_FLAGS_NONE);
    658654                ASSERT((call->flags & IPC_CALL_ANSWERED) ||
     
    666662                if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
    667663                        atomic_dec(&TASK->active_calls);
     664               
    668665                ipc_call_free(call);
    669666        }
    670667}
    671668
    672 
    673 /** Initilize IPC subsystem */
     669/** Initilize IPC subsystem
     670 *
     671 */
    674672void ipc_init(void)
    675673{
     
    680678}
    681679
    682 
    683680/** List answerbox contents.
    684681 *
    685  * @param taskid        Task ID.
     682 * @param taskid Task ID.
     683 *
    686684 */
    687685void ipc_print_task(task_id_t taskid)
    688686{
    689         task_t *task;
    690         int i;
    691         call_t *call;
    692         link_t *tmp;
    693         ipl_t ipl;
    694        
    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);
     687        irq_spinlock_lock(&tasks_lock, true);
     688        task_t *task = task_find_by_id(taskid);
     689       
    701690        if (!task) {
    702                 interrupts_restore(ipl);
     691                irq_spinlock_unlock(&tasks_lock, true);
    703692                return;
    704693        }
    705 
     694       
     695        /* Hand-over-hand locking */
     696        irq_spinlock_exchange(&tasks_lock, &task->lock);
     697       
    706698        /* Print opened phones & details */
    707699        printf("PHONE:\n");
     700       
     701        size_t i;
    708702        for (i = 0; i < IPC_MAX_PHONES; i++) {
    709703                if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
     
    711705                        continue;
    712706                }
     707               
    713708                if (task->phones[i].state != IPC_PHONE_FREE) {
    714                         printf("%d: ", i);
     709                        printf("%" PRIs ": ", i);
     710                       
    715711                        switch (task->phones[i].state) {
    716712                        case IPC_PHONE_CONNECTING:
     
    718714                                break;
    719715                        case IPC_PHONE_CONNECTED:
    720                                 printf("connected to: %p ", 
    721                                        task->phones[i].callee);
     716                                printf("connected to: %p ",
     717                                    task->phones[i].callee);
    722718                                break;
    723719                        case IPC_PHONE_SLAMMED:
    724720                                printf("slammed by: %p ",
    725                                        task->phones[i].callee);
     721                                    task->phones[i].callee);
    726722                                break;
    727723                        case IPC_PHONE_HUNGUP:
    728724                                printf("hung up - was: %p ",
    729                                        task->phones[i].callee);
     725                                    task->phones[i].callee);
    730726                                break;
    731727                        default:
    732728                                break;
    733729                        }
    734                         printf("active: %ld\n",
     730                       
     731                        printf("active: %" PRIun "\n",
    735732                            atomic_get(&task->phones[i].active_calls));
    736733                }
     734               
    737735                mutex_unlock(&task->phones[i].lock);
    738736        }
    739 
    740 
     737       
     738        irq_spinlock_lock(&task->answerbox.lock, false);
     739       
     740        link_t *cur;
     741       
    741742        /* Print answerbox - calls */
    742         spinlock_lock(&task->answerbox.lock);
    743743        printf("ABOX - CALLS:\n");
    744         for (tmp = task->answerbox.calls.next; tmp != &task->answerbox.calls;
    745             tmp = tmp->next) {
    746                 call = list_get_instance(tmp, call_t, link);
     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);
    747747                printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    748748                    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
     
    754754                    call->flags);
    755755        }
    756         /* Print answerbox - calls */
     756       
     757        /* Print answerbox - dispatched calls */
    757758        printf("ABOX - DISPATCHED CALLS:\n");
    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);
     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);
    762763                printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
    763764                    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
     
    769770                    call->flags);
    770771        }
    771         /* Print answerbox - calls */
     772       
     773        /* Print answerbox - answers */
    772774        printf("ABOX - ANSWERS:\n");
    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);
     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);
    777779                printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun
    778780                    " A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n",
     
    782784                    call->flags);
    783785        }
    784 
    785         spinlock_unlock(&task->answerbox.lock);
    786         spinlock_unlock(&task->lock);
    787         interrupts_restore(ipl);
     786       
     787        irq_spinlock_unlock(&task->answerbox.lock, false);
     788        irq_spinlock_unlock(&task->lock, true);
    788789}
    789790
Note: See TracChangeset for help on using the changeset viewer.