Ignore:
File:
1 edited

Legend:

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

    rf97f1e51 r466e95f7  
    4545#include <ipc/kbox.h>
    4646#include <ipc/event.h>
     47#include <ipc/sysipc_ops.h>
     48#include <ipc/sysipc_priv.h>
    4749#include <errno.h>
    4850#include <mm/slab.h>
     
    7173{
    7274        memsetb(call, sizeof(*call), 0);
    73         call->callerbox = &TASK->answerbox;
    74         call->sender = TASK;
     75        spinlock_initialize(&call->forget_lock, "forget_lock");
     76        call->active = false;
     77        call->forget = false;
     78        call->sender = NULL;
    7579        call->buffer = NULL;
     80}
     81
     82void ipc_call_hold(call_t *call)
     83{
     84        atomic_inc(&call->refcnt);
     85}
     86
     87void 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        }
    7694}
    7795
     
    84102 *
    85103 * @return If flags permit it, return NULL, or initialized kernel
    86  *         call structure.
     104 *         call structure with one reference.
    87105 *
    88106 */
     
    90108{
    91109        call_t *call = slab_alloc(ipc_call_slab, flags);
    92         if (call)
     110        if (call) {
    93111                _ipc_call_init(call);
     112                ipc_call_hold(call);
     113        }
    94114       
    95115        return call;
     
    103123void ipc_call_free(call_t *call)
    104124{
    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);
     125        ipc_call_release(call);
    109126}
    110127
     
    120137        irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
    121138        waitq_initialize(&box->wq);
    122         link_initialize(&box->sync_box_link);
    123139        list_initialize(&box->connected_phones);
    124140        list_initialize(&box->calls);
     
    134150 * @param phone Initialized phone structure.
    135151 * @param box   Initialized answerbox structure.
    136  *
    137  */
    138 void ipc_phone_connect(phone_t *phone, answerbox_t *box)
    139 {
     152 * @return      True if the phone was connected, false otherwise.
     153 */
     154bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
     155{
     156        bool active;
     157
    140158        mutex_lock(&phone->lock);
    141        
    142         phone->state = IPC_PHONE_CONNECTED;
    143         phone->callee = box;
    144        
    145159        irq_spinlock_lock(&box->lock, true);
    146         list_append(&phone->link, &box->connected_phones);
     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
    147168        irq_spinlock_unlock(&box->lock, true);
    148        
    149169        mutex_unlock(&phone->lock);
     170
     171        return active;
    150172}
    151173
     
    153175 *
    154176 * @param phone Phone structure to be initialized.
    155  *
    156  */
    157 void ipc_phone_init(phone_t *phone)
     177 * @param caller Owning task.
     178 *
     179 */
     180void ipc_phone_init(phone_t *phone, task_t *caller)
    158181{
    159182        mutex_initialize(&phone->lock, MUTEX_PASSIVE);
     183        phone->caller = caller;
    160184        phone->callee = NULL;
    161185        phone->state = IPC_PHONE_FREE;
     
    163187}
    164188
    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  */
    173 int 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 
    208189/** Answer a message which was not dispatched and is not listed in any queue.
    209190 *
     
    212193 *
    213194 */
    214 static 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        
     195void _ipc_answer_free_call(call_t *call, bool selflocked)
     196{
    219197        /* Count sent answer */
    220198        irq_spinlock_lock(&TASK->lock, true);
    221199        TASK->ipc_info.answer_sent++;
    222200        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);
     218                }
     219        }
     220        spinlock_unlock(&call->forget_lock);
     221
     222        answerbox_t *callerbox = &call->sender->answerbox;
     223        bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox));
    223224       
    224225        call->flags |= IPC_CALL_ANSWERED;
    225226       
    226         if (call->flags & IPC_CALL_FORWARDED) {
    227                 if (call->caller_phone) {
    228                         /* Demasquerade the caller phone. */
    229                         call->data.phone = call->caller_phone;
    230                 }
    231         }
    232 
    233227        call->data.task_id = TASK->taskid;
    234228       
     
    236230                irq_spinlock_lock(&callerbox->lock, true);
    237231       
    238         list_append(&call->link, &callerbox->answers);
     232        list_append(&call->ab_link, &callerbox->answers);
    239233       
    240234        if (do_lock)
     
    254248        /* Remove from active box */
    255249        irq_spinlock_lock(&box->lock, true);
    256         list_remove(&call->link);
     250        list_remove(&call->ab_link);
    257251        irq_spinlock_unlock(&box->lock, true);
    258252       
    259253        /* Send back answer */
    260254        _ipc_answer_free_call(call, false);
     255}
     256
     257static 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;
    261272}
    262273
     
    273284void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err)
    274285{
    275         call->data.phone = phone;
    276         atomic_inc(&phone->active_calls);
     286        _ipc_call_actions_internal(phone, call);
    277287        IPC_SET_RETVAL(call->data, err);
    278288        _ipc_answer_free_call(call, false);
     
    288298static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
    289299{
     300        task_t *caller = phone->caller;
     301
    290302        /* Count sent ipc 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         }
     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);
    300309       
    301310        irq_spinlock_lock(&box->lock, true);
    302         list_append(&call->link, &box->calls);
     311        list_append(&call->ab_link, &box->calls);
    303312        irq_spinlock_unlock(&box->lock, true);
    304313       
     
    320329        if (phone->state != IPC_PHONE_CONNECTED) {
    321330                mutex_unlock(&phone->lock);
    322                 if (call->flags & IPC_CALL_FORWARDED) {
    323                         IPC_SET_RETVAL(call->data, EFORWARD);
    324                         _ipc_answer_free_call(call, false);
    325                 } else {
     331                if (!(call->flags & IPC_CALL_FORWARDED)) {
    326332                        if (phone->state == IPC_PHONE_HUNGUP)
    327333                                ipc_backsend_err(phone, call, EHANGUP);
     
    370376                call_t *call = ipc_call_alloc(0);
    371377                IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
     378                call->request_method = IPC_M_PHONE_HUNGUP;
    372379                call->flags |= IPC_CALL_DISCARD_ANSWER;
    373380                _ipc_call(phone, box, call);
     
    401408        TASK->ipc_info.forwarded++;
    402409        irq_spinlock_pass(&TASK->lock, &oldbox->lock);
    403         list_remove(&call->link);
     410        list_remove(&call->ab_link);
    404411        irq_spinlock_unlock(&oldbox->lock, true);
    405412       
    406413        if (mode & IPC_FF_ROUTE_FROM_ME) {
    407                 if (!call->caller_phone)
    408                         call->caller_phone = call->data.phone;
    409414                call->data.phone = newphone;
    410415                call->data.task_id = TASK->taskid;
     
    451456               
    452457                request = list_get_instance(list_first(&box->irq_notifs),
    453                     call_t, link);
    454                 list_remove(&request->link);
     458                    call_t, ab_link);
     459                list_remove(&request->ab_link);
    455460               
    456461                irq_spinlock_unlock(&box->irq_lock, false);
     
    461466                /* Handle asynchronous answers */
    462467                request = list_get_instance(list_first(&box->answers),
    463                     call_t, link);
    464                 list_remove(&request->link);
    465                 atomic_dec(&request->data.phone->active_calls);
     468                    call_t, ab_link);
     469                list_remove(&request->ab_link);
     470                atomic_dec(&request->caller_phone->active_calls);
    466471        } else if (!list_empty(&box->calls)) {
    467472                /* Count received call */
     
    470475                /* Handle requests */
    471476                request = list_get_instance(list_first(&box->calls),
    472                     call_t, link);
    473                 list_remove(&request->link);
     477                    call_t, ab_link);
     478                list_remove(&request->ab_link);
    474479               
    475480                /* Append request to dispatch queue */
    476                 list_append(&request->link, &box->dispatched_calls);
     481                list_append(&request->ab_link, &box->dispatched_calls);
    477482        } else {
    478483                /* This can happen regularly after ipc_cleanup */
     
    494499/** Answer all calls from list with EHANGUP answer.
    495500 *
     501 * @param box Answerbox with the list.
    496502 * @param lst Head of the list to be cleaned up.
    497  *
    498  */
    499 void ipc_cleanup_call_list(list_t *lst)
    500 {
     503 */
     504void ipc_cleanup_call_list(answerbox_t *box, list_t *lst)
     505{
     506        irq_spinlock_lock(&box->lock, true);
    501507        while (!list_empty(lst)) {
    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                
     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;
    508519                IPC_SET_RETVAL(call->data, EHANGUP);
     520                answer_preprocess(call, &old);
    509521                _ipc_answer_free_call(call, true);
    510         }
     522
     523                irq_spinlock_lock(&box->lock, true);
     524        }
     525        irq_spinlock_unlock(&box->lock, true);
    511526}
    512527
     
    546561                        mutex_unlock(&phone->lock);
    547562                        irq_spinlock_unlock(&box->lock, true);
    548                        
     563
     564                        // FIXME: phone can become deallocated at any time now
     565
    549566                        /*
    550567                         * Send one message to the answerbox for each
     
    554571                         */
    555572                        IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
     573                        call->request_method = IPC_M_PHONE_HUNGUP;
    556574                        call->flags |= IPC_CALL_DISCARD_ANSWER;
    557575                        _ipc_call(phone, box, call);
     
    574592}
    575593
     594static void ipc_forget_all_active_calls(void)
     595{
     596        call_t *call;
     597
     598restart:
     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. */
     650static void ipc_wait_for_all_answered_calls(void)
     651{
     652        call_t *call;
     653        size_t i;
     654
     655restart:
     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
    576717/** Clean up all IPC communication of the current task.
    577718 *
     
    582723void ipc_cleanup(void)
    583724{
     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
    584735        /* Disconnect all our phones ('ipc_phone_hangup') */
    585         size_t i;
    586         for (i = 0; i < IPC_MAX_PHONES; i++)
     736        for (size_t i = 0; i < IPC_MAX_PHONES; i++)
    587737                ipc_phone_hangup(&TASK->phones[i]);
    588738       
     
    602752       
    603753        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    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         }
     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();
    665760}
    666761
     
    674769        ipc_answerbox_slab = slab_cache_create("answerbox_t",
    675770            sizeof(answerbox_t), 0, NULL, NULL, 0);
     771}
     772
     773
     774static 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        }
    676805}
    677806
     
    747876       
    748877        printf(" --- incomming calls ---\n");
    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        
     878        ipc_print_call_list(&task->answerbox.calls);
    768879        printf(" --- dispatched calls ---\n");
    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        
     880        ipc_print_call_list(&task->answerbox.dispatched_calls);
    788881        printf(" --- incoming answers ---\n");
    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         }
     882        ipc_print_call_list(&task->answerbox.answers);
    807883       
    808884        irq_spinlock_unlock(&task->answerbox.lock, false);
Note: See TracChangeset for help on using the changeset viewer.