Ignore:
File:
1 edited

Legend:

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

    r466e95f7 rf97f1e51  
    4545#include <ipc/kbox.h>
    4646#include <ipc/event.h>
    47 #include <ipc/sysipc_ops.h>
    48 #include <ipc/sysipc_priv.h>
    4947#include <errno.h>
    5048#include <mm/slab.h>
     
    7371{
    7472        memsetb(call, sizeof(*call), 0);
    75         spinlock_initialize(&call->forget_lock, "forget_lock");
    76         call->active = false;
    77         call->forget = false;
    78         call->sender = NULL;
     73        call->callerbox = &TASK->answerbox;
     74        call->sender = TASK;
    7975        call->buffer = NULL;
    80 }
    81 
    82 void ipc_call_hold(call_t *call)
    83 {
    84         atomic_inc(&call->refcnt);
    85 }
    86 
    87 void ipc_call_release(call_t *call)
    88 {
    89         if (atomic_predec(&call->refcnt) == 0) {
    90                 if (call->buffer)
    91                         free(call->buffer);
    92                 slab_free(ipc_call_slab, call);
    93         }
    9476}
    9577
     
    10284 *
    10385 * @return If flags permit it, return NULL, or initialized kernel
    104  *         call structure with one reference.
     86 *         call structure.
    10587 *
    10688 */
     
    10890{
    10991        call_t *call = slab_alloc(ipc_call_slab, flags);
    110         if (call) {
     92        if (call)
    11193                _ipc_call_init(call);
    112                 ipc_call_hold(call);
    113         }
    11494       
    11595        return call;
     
    123103void ipc_call_free(call_t *call)
    124104{
    125         ipc_call_release(call);
     105        /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
     106        if (call->buffer)
     107                free(call->buffer);
     108        slab_free(ipc_call_slab, call);
    126109}
    127110
     
    137120        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    138121        waitq_initialize(&box->wq);
     122        link_initialize(&box->sync_box_link);
    139123        list_initialize(&box->connected_phones);
    140124        list_initialize(&box->calls);
     
    150134 * @param phone Initialized phone structure.
    151135 * @param box   Initialized answerbox structure.
    152  * @return      True if the phone was connected, false otherwise.
    153  */
    154 bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
    155 {
    156         bool active;
    157 
     136 *
     137 */
     138void ipc_phone_connect(phone_t *phone, answerbox_t *box)
     139{
    158140        mutex_lock(&phone->lock);
     141       
     142        phone->state = IPC_PHONE_CONNECTED;
     143        phone->callee = box;
     144       
    159145        irq_spinlock_lock(&box->lock, true);
    160 
    161         active = box->active;
    162         if (active) {
    163                 phone->state = IPC_PHONE_CONNECTED;
    164                 phone->callee = box;
    165                 list_append(&phone->link, &box->connected_phones);
    166         }
    167 
     146        list_append(&phone->link, &box->connected_phones);
    168147        irq_spinlock_unlock(&box->lock, true);
     148       
    169149        mutex_unlock(&phone->lock);
    170 
    171         return active;
    172150}
    173151
     
    175153 *
    176154 * @param phone Phone structure to be initialized.
    177  * @param caller Owning task.
    178  *
    179  */
    180 void ipc_phone_init(phone_t *phone, task_t *caller)
     155 *
     156 */
     157void ipc_phone_init(phone_t *phone)
    181158{
    182159        mutex_initialize(&phone->lock, MUTEX_PASSIVE);
    183         phone->caller = caller;
    184160        phone->callee = NULL;
    185161        phone->state = IPC_PHONE_FREE;
     
    187163}
    188164
     165/** Helper function to facilitate synchronous calls.
     166 *
     167 * @param phone   Destination kernel phone structure.
     168 * @param request Call structure with request.
     169 *
     170 * @return EOK on success or EINTR if the sleep was interrupted.
     171 *
     172 */
     173int ipc_call_sync(phone_t *phone, call_t *request)
     174{
     175        answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
     176        ipc_answerbox_init(sync_box, TASK);
     177       
     178        /*
     179         * Put the answerbox on the TASK's list of synchronous answerboxes so
     180         * that it can be cleaned up if the call is interrupted.
     181         */
     182        irq_spinlock_lock(&TASK->lock, true);
     183        list_append(&sync_box->sync_box_link, &TASK->sync_boxes);
     184        irq_spinlock_unlock(&TASK->lock, true);
     185       
     186        /* We will receive data in a special box. */
     187        request->callerbox = sync_box;
     188       
     189        ipc_call(phone, request);
     190        if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
     191            SYNCH_FLAGS_INTERRUPTIBLE)) {
     192                /* The answerbox and the call will be freed by ipc_cleanup(). */
     193                return EINTR;
     194        }
     195       
     196        /*
     197         * The answer arrived without interruption so we can remove the
     198         * answerbox from the TASK's list of synchronous answerboxes.
     199         */
     200        irq_spinlock_lock(&TASK->lock, true);
     201        list_remove(&sync_box->sync_box_link);
     202        irq_spinlock_unlock(&TASK->lock, true);
     203       
     204        slab_free(ipc_answerbox_slab, sync_box);
     205        return EOK;
     206}
     207
    189208/** Answer a message which was not dispatched and is not listed in any queue.
    190209 *
     
    193212 *
    194213 */
    195 void _ipc_answer_free_call(call_t *call, bool selflocked)
    196 {
     214static void _ipc_answer_free_call(call_t *call, bool selflocked)
     215{
     216        answerbox_t *callerbox = call->callerbox;
     217        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
     218       
    197219        /* Count sent answer */
    198220        irq_spinlock_lock(&TASK->lock, true);
    199221        TASK->ipc_info.answer_sent++;
    200222        irq_spinlock_unlock(&TASK->lock, true);
    201 
    202         spinlock_lock(&call->forget_lock);
    203         if (call->forget) {
    204                 /* This is a forgotten call and call->sender is not valid. */
    205                 spinlock_unlock(&call->forget_lock);
    206                 ipc_call_free(call);
    207                 return;
    208         } else {
    209                 /*
    210                  * If the call is still active, i.e. it was answered
    211                  * in a non-standard way, remove the call from the
    212                  * sender's active call list.
    213                  */
    214                 if (call->active) {
    215                         spinlock_lock(&call->sender->active_calls_lock);
    216                         list_remove(&call->ta_link);
    217                         spinlock_unlock(&call->sender->active_calls_lock);
     223       
     224        call->flags |= IPC_CALL_ANSWERED;
     225       
     226        if (call->flags & IPC_CALL_FORWARDED) {
     227                if (call->caller_phone) {
     228                        /* Demasquerade the caller phone. */
     229                        call->data.phone = call->caller_phone;
    218230                }
    219231        }
    220         spinlock_unlock(&call->forget_lock);
    221 
    222         answerbox_t *callerbox = &call->sender->answerbox;
    223         bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox));
    224        
    225         call->flags |= IPC_CALL_ANSWERED;
    226        
     232
    227233        call->data.task_id = TASK->taskid;
    228234       
     
    230236                irq_spinlock_lock(&callerbox->lock, true);
    231237       
    232         list_append(&call->ab_link, &callerbox->answers);
     238        list_append(&call->link, &callerbox->answers);
    233239       
    234240        if (do_lock)
     
    248254        /* Remove from active box */
    249255        irq_spinlock_lock(&box->lock, true);
    250         list_remove(&call->ab_link);
     256        list_remove(&call->link);
    251257        irq_spinlock_unlock(&box->lock, true);
    252258       
    253259        /* Send back answer */
    254260        _ipc_answer_free_call(call, false);
    255 }
    256 
    257 static void _ipc_call_actions_internal(phone_t *phone, call_t *call)
    258 {
    259         task_t *caller = phone->caller;
    260 
    261         atomic_inc(&phone->active_calls);
    262         call->caller_phone = phone;
    263         call->sender = caller;
    264 
    265         call->active = true;
    266         spinlock_lock(&caller->active_calls_lock);
    267         list_append(&call->ta_link, &caller->active_calls);
    268         spinlock_unlock(&caller->active_calls_lock);
    269 
    270         call->data.phone = phone;
    271         call->data.task_id = caller->taskid;
    272261}
    273262
     
    284273void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err)
    285274{
    286         _ipc_call_actions_internal(phone, call);
     275        call->data.phone = phone;
     276        atomic_inc(&phone->active_calls);
    287277        IPC_SET_RETVAL(call->data, err);
    288278        _ipc_answer_free_call(call, false);
     
    298288static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
    299289{
    300         task_t *caller = phone->caller;
    301 
    302290        /* Count sent ipc call */
    303         irq_spinlock_lock(&caller->lock, true);
    304         caller->ipc_info.call_sent++;
    305         irq_spinlock_unlock(&caller->lock, true);
    306        
    307         if (!(call->flags & IPC_CALL_FORWARDED))
    308                 _ipc_call_actions_internal(phone, call);
     291        irq_spinlock_lock(&TASK->lock, true);
     292        TASK->ipc_info.call_sent++;
     293        irq_spinlock_unlock(&TASK->lock, true);
     294       
     295        if (!(call->flags & IPC_CALL_FORWARDED)) {
     296                atomic_inc(&phone->active_calls);
     297                call->data.phone = phone;
     298                call->data.task_id = TASK->taskid;
     299        }
    309300       
    310301        irq_spinlock_lock(&box->lock, true);
    311         list_append(&call->ab_link, &box->calls);
     302        list_append(&call->link, &box->calls);
    312303        irq_spinlock_unlock(&box->lock, true);
    313304       
     
    329320        if (phone->state != IPC_PHONE_CONNECTED) {
    330321                mutex_unlock(&phone->lock);
    331                 if (!(call->flags & IPC_CALL_FORWARDED)) {
     322                if (call->flags & IPC_CALL_FORWARDED) {
     323                        IPC_SET_RETVAL(call->data, EFORWARD);
     324                        _ipc_answer_free_call(call, false);
     325                } else {
    332326                        if (phone->state == IPC_PHONE_HUNGUP)
    333327                                ipc_backsend_err(phone, call, EHANGUP);
     
    376370                call_t *call = ipc_call_alloc(0);
    377371                IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
    378                 call->request_method = IPC_M_PHONE_HUNGUP;
    379372                call->flags |= IPC_CALL_DISCARD_ANSWER;
    380373                _ipc_call(phone, box, call);
     
    408401        TASK->ipc_info.forwarded++;
    409402        irq_spinlock_pass(&TASK->lock, &oldbox->lock);
    410         list_remove(&call->ab_link);
     403        list_remove(&call->link);
    411404        irq_spinlock_unlock(&oldbox->lock, true);
    412405       
    413406        if (mode & IPC_FF_ROUTE_FROM_ME) {
     407                if (!call->caller_phone)
     408                        call->caller_phone = call->data.phone;
    414409                call->data.phone = newphone;
    415410                call->data.task_id = TASK->taskid;
     
    456451               
    457452                request = list_get_instance(list_first(&box->irq_notifs),
    458                     call_t, ab_link);
    459                 list_remove(&request->ab_link);
     453                    call_t, link);
     454                list_remove(&request->link);
    460455               
    461456                irq_spinlock_unlock(&box->irq_lock, false);
     
    466461                /* Handle asynchronous answers */
    467462                request = list_get_instance(list_first(&box->answers),
    468                     call_t, ab_link);
    469                 list_remove(&request->ab_link);
    470                 atomic_dec(&request->caller_phone->active_calls);
     463                    call_t, link);
     464                list_remove(&request->link);
     465                atomic_dec(&request->data.phone->active_calls);
    471466        } else if (!list_empty(&box->calls)) {
    472467                /* Count received call */
     
    475470                /* Handle requests */
    476471                request = list_get_instance(list_first(&box->calls),
    477                     call_t, ab_link);
    478                 list_remove(&request->ab_link);
     472                    call_t, link);
     473                list_remove(&request->link);
    479474               
    480475                /* Append request to dispatch queue */
    481                 list_append(&request->ab_link, &box->dispatched_calls);
     476                list_append(&request->link, &box->dispatched_calls);
    482477        } else {
    483478                /* This can happen regularly after ipc_cleanup */
     
    499494/** Answer all calls from list with EHANGUP answer.
    500495 *
    501  * @param box Answerbox with the list.
    502496 * @param lst Head of the list to be cleaned up.
    503  */
    504 void ipc_cleanup_call_list(answerbox_t *box, list_t *lst)
    505 {
    506         irq_spinlock_lock(&box->lock, true);
     497 *
     498 */
     499void ipc_cleanup_call_list(list_t *lst)
     500{
    507501        while (!list_empty(lst)) {
    508                 call_t *call = list_get_instance(list_first(lst), call_t,
    509                     ab_link);
    510                
    511                 list_remove(&call->ab_link);
    512 
    513                 irq_spinlock_unlock(&box->lock, true);
    514 
    515                 if (lst == &box->calls)
    516                         SYSIPC_OP(request_process, call, box);
    517 
    518                 ipc_data_t old = call->data;
     502                call_t *call = list_get_instance(list_first(lst), call_t, link);
     503                if (call->buffer)
     504                        free(call->buffer);
     505               
     506                list_remove(&call->link);
     507               
    519508                IPC_SET_RETVAL(call->data, EHANGUP);
    520                 answer_preprocess(call, &old);
    521509                _ipc_answer_free_call(call, true);
    522 
    523                 irq_spinlock_lock(&box->lock, true);
    524         }
    525         irq_spinlock_unlock(&box->lock, true);
     510        }
    526511}
    527512
     
    561546                        mutex_unlock(&phone->lock);
    562547                        irq_spinlock_unlock(&box->lock, true);
    563 
    564                         // FIXME: phone can become deallocated at any time now
    565 
     548                       
    566549                        /*
    567550                         * Send one message to the answerbox for each
     
    571554                         */
    572555                        IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
    573                         call->request_method = IPC_M_PHONE_HUNGUP;
    574556                        call->flags |= IPC_CALL_DISCARD_ANSWER;
    575557                        _ipc_call(phone, box, call);
     
    592574}
    593575
    594 static void ipc_forget_all_active_calls(void)
    595 {
    596         call_t *call;
    597 
    598 restart:
    599         spinlock_lock(&TASK->active_calls_lock);
    600         if (list_empty(&TASK->active_calls)) {
    601                 /*
    602                  * We are done, there are no more active calls.
    603                  * Nota bene: there may still be answers waiting for pick up.
    604                  */
    605                 spinlock_unlock(&TASK->active_calls_lock);     
    606                 return;
    607         }
    608        
    609         call = list_get_instance(list_first(&TASK->active_calls), call_t,
    610             ta_link);
    611 
    612         if (!spinlock_trylock(&call->forget_lock)) {
    613                 /*
    614                  * Avoid deadlock and let async_answer() or
    615                  *  _ipc_answer_free_call() win the race to dequeue the first
    616                  * call on the list.
    617                  */
    618                 spinlock_unlock(&TASK->active_calls_lock);     
    619                 goto restart;
    620         }
    621 
    622         /*
    623          * Forget the call and donate it to the task which holds up the answer.
    624          */
    625 
    626         call->forget = true;
    627         call->sender = NULL;
    628         list_remove(&call->ta_link);
    629 
    630         /*
    631          * The call may be freed by _ipc_answer_free_call() before we are done
    632          * with it; to avoid working with a destroyed call_t structure, we
    633          * must hold a reference to it.
    634          */
    635         ipc_call_hold(call);
    636 
    637         spinlock_unlock(&call->forget_lock);
    638         spinlock_unlock(&TASK->active_calls_lock);
    639 
    640         atomic_dec(&call->caller_phone->active_calls);
    641 
    642         SYSIPC_OP(request_forget, call);
    643 
    644         ipc_call_release(call);
    645 
    646         goto restart;
    647 }
    648 
    649 /** Wait for all answers to asynchronous calls to arrive. */
    650 static void ipc_wait_for_all_answered_calls(void)
    651 {
    652         call_t *call;
    653         size_t i;
    654 
    655 restart:
    656         /*
    657          * Go through all phones, until they are all free.
    658          * Locking is needed as there may be connection handshakes in progress.
    659          */
    660         for (i = 0; i < IPC_MAX_PHONES; i++) {
    661                 phone_t *phone = &TASK->phones[i];
    662 
    663                 mutex_lock(&phone->lock);       
    664                 if ((phone->state == IPC_PHONE_HUNGUP) &&
    665                     (atomic_get(&phone->active_calls) == 0)) {
    666                         phone->state = IPC_PHONE_FREE;
    667                         phone->callee = NULL;
    668                 }
    669 
    670                 /*
    671                  * We might have had some IPC_PHONE_CONNECTING phones at the
    672                  * beginning of ipc_cleanup(). Depending on whether these were
    673                  * forgotten or answered, they will eventually enter the
    674                  * IPC_PHONE_FREE or IPC_PHONE_CONNECTED states, respectively.
    675                  * In the latter case, the other side may slam the open phones
    676                  * at any time, in which case we will get an IPC_PHONE_SLAMMED
    677                  * phone.
    678                  */
    679                 if ((phone->state == IPC_PHONE_CONNECTED) ||
    680                     (phone->state == IPC_PHONE_SLAMMED)) {
    681                         mutex_unlock(&phone->lock);
    682                         ipc_phone_hangup(phone);
    683                         /*
    684                          * Now there may be one extra active call, which needs
    685                          * to be forgotten.
    686                          */
    687                         ipc_forget_all_active_calls();
    688                         goto restart;
    689                 }
    690 
    691                 /*
    692                  * If the hangup succeeded, it has sent a HANGUP message, the
    693                  * IPC is now in HUNGUP state, we wait for the reply to come
    694                  */
    695                 if (phone->state != IPC_PHONE_FREE) {
    696                         mutex_unlock(&phone->lock);
    697                         break;
    698                 }
    699 
    700                 mutex_unlock(&phone->lock);
    701         }
    702                
    703         /* Got into cleanup */
    704         if (i == IPC_MAX_PHONES)
    705                 return;
    706                
    707         call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
    708             SYNCH_FLAGS_NONE);
    709         ASSERT(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
    710 
    711         SYSIPC_OP(answer_process, call);
    712 
    713         ipc_call_free(call);
    714         goto restart;
    715 }
    716 
    717576/** Clean up all IPC communication of the current task.
    718577 *
     
    723582void ipc_cleanup(void)
    724583{
    725         /*
    726          * Mark the answerbox as inactive.
    727          *
    728          * The main purpose for doing this is to prevent any pending callback
    729          * connections from getting established beyond this point.
    730          */
    731         irq_spinlock_lock(&TASK->answerbox.lock, true);
    732         TASK->answerbox.active = false;
    733         irq_spinlock_unlock(&TASK->answerbox.lock, true);
    734 
    735584        /* Disconnect all our phones ('ipc_phone_hangup') */
    736         for (size_t i = 0; i < IPC_MAX_PHONES; i++)
     585        size_t i;
     586        for (i = 0; i < IPC_MAX_PHONES; i++)
    737587                ipc_phone_hangup(&TASK->phones[i]);
    738588       
     
    752602       
    753603        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    754         ipc_cleanup_call_list(&TASK->answerbox, &TASK->answerbox.calls);
    755         ipc_cleanup_call_list(&TASK->answerbox,
    756             &TASK->answerbox.dispatched_calls);
    757 
    758         ipc_forget_all_active_calls();
    759         ipc_wait_for_all_answered_calls();
     604        irq_spinlock_lock(&TASK->answerbox.lock, true);
     605        ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
     606        ipc_cleanup_call_list(&TASK->answerbox.calls);
     607        irq_spinlock_unlock(&TASK->answerbox.lock, true);
     608       
     609        /* Wait for all answers to interrupted synchronous calls to arrive */
     610        ipl_t ipl = interrupts_disable();
     611        while (!list_empty(&TASK->sync_boxes)) {
     612                answerbox_t *box = list_get_instance(
     613                    list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);
     614               
     615                list_remove(&box->sync_box_link);
     616                call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
     617                    SYNCH_FLAGS_NONE);
     618                ipc_call_free(call);
     619                slab_free(ipc_answerbox_slab, box);
     620        }
     621        interrupts_restore(ipl);
     622       
     623        /* Wait for all answers to asynchronous calls to arrive */
     624        while (true) {
     625                /*
     626                 * Go through all phones, until they are all FREE
     627                 * Locking is not needed, no one else should modify
     628                 * it when we are in cleanup
     629                 */
     630                for (i = 0; i < IPC_MAX_PHONES; i++) {
     631                        if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
     632                            atomic_get(&TASK->phones[i].active_calls) == 0) {
     633                                TASK->phones[i].state = IPC_PHONE_FREE;
     634                                TASK->phones[i].callee = NULL;
     635                        }
     636                       
     637                        /*
     638                         * Just for sure, we might have had some
     639                         * IPC_PHONE_CONNECTING phones
     640                         */
     641                        if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
     642                                ipc_phone_hangup(&TASK->phones[i]);
     643                       
     644                        /*
     645                         * If the hangup succeeded, it has sent a HANGUP
     646                         * message, the IPC is now in HUNGUP state, we
     647                         * wait for the reply to come
     648                         */
     649                       
     650                        if (TASK->phones[i].state != IPC_PHONE_FREE)
     651                                break;
     652                }
     653               
     654                /* Got into cleanup */
     655                if (i == IPC_MAX_PHONES)
     656                        break;
     657               
     658                call_t *call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
     659                    SYNCH_FLAGS_NONE);
     660                ASSERT((call->flags & IPC_CALL_ANSWERED) ||
     661                    (call->flags & IPC_CALL_NOTIF));
     662               
     663                ipc_call_free(call);
     664        }
    760665}
    761666
     
    769674        ipc_answerbox_slab = slab_cache_create("answerbox_t",
    770675            sizeof(answerbox_t), 0, NULL, NULL, 0);
    771 }
    772 
    773 
    774 static void ipc_print_call_list(list_t *list)
    775 {
    776         list_foreach(*list, cur) {
    777                 call_t *call = list_get_instance(cur, call_t, ab_link);
    778                
    779 #ifdef __32_BITS__
    780                 printf("%10p ", call);
    781 #endif
    782                
    783 #ifdef __64_BITS__
    784                 printf("%18p ", call);
    785 #endif
    786                
    787                 spinlock_lock(&call->forget_lock);
    788 
    789                 printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
    790                     " %-6" PRIun " %-6" PRIun " %-7x",
    791                     IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
    792                     IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
    793                     IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
    794                     call->flags);
    795 
    796                 if (call->forget) {
    797                         printf(" ? (call forgotten)\n");
    798                 } else {
    799                         printf(" %" PRIu64 " (%s)\n",
    800                             call->sender->taskid, call->sender->name);
    801                 }
    802 
    803                 spinlock_unlock(&call->forget_lock);
    804         }
    805676}
    806677
     
    876747       
    877748        printf(" --- incomming calls ---\n");
    878         ipc_print_call_list(&task->answerbox.calls);
     749        list_foreach(task->answerbox.calls, cur) {
     750                call_t *call = list_get_instance(cur, call_t, link);
     751               
     752#ifdef __32_BITS__
     753                printf("%10p ", call);
     754#endif
     755               
     756#ifdef __64_BITS__
     757                printf("%18p ", call);
     758#endif
     759               
     760                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     761                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
     762                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
     763                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
     764                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
     765                    call->flags, call->sender->taskid, call->sender->name);
     766        }
     767       
    879768        printf(" --- dispatched calls ---\n");
    880         ipc_print_call_list(&task->answerbox.dispatched_calls);
     769        list_foreach(task->answerbox.dispatched_calls, cur) {
     770                call_t *call = list_get_instance(cur, call_t, link);
     771               
     772#ifdef __32_BITS__
     773                printf("%10p ", call);
     774#endif
     775               
     776#ifdef __64_BITS__
     777                printf("%18p ", call);
     778#endif
     779               
     780                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     781                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
     782                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
     783                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
     784                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
     785                    call->flags, call->sender->taskid, call->sender->name);
     786        }
     787       
    881788        printf(" --- incoming answers ---\n");
    882         ipc_print_call_list(&task->answerbox.answers);
     789        list_foreach(task->answerbox.answers, cur) {
     790                call_t *call = list_get_instance(cur, call_t, link);
     791               
     792#ifdef __32_BITS__
     793                printf("%10p ", call);
     794#endif
     795               
     796#ifdef __64_BITS__
     797                printf("%18p ", call);
     798#endif
     799               
     800                printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
     801                    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
     802                    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
     803                    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
     804                    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
     805                    call->flags, call->sender->taskid, call->sender->name);
     806        }
    883807       
    884808        irq_spinlock_unlock(&task->answerbox.lock, false);
Note: See TracChangeset for help on using the changeset viewer.