Changes in kernel/generic/src/ipc/ipc.c [ab34cc9:466e95f7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
rab34cc9 r466e95f7 45 45 #include <ipc/kbox.h> 46 46 #include <ipc/event.h> 47 #include <ipc/sysipc_ops.h> 48 #include <ipc/sysipc_priv.h> 47 49 #include <errno.h> 48 50 #include <mm/slab.h> … … 71 73 { 72 74 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; 75 79 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 } 76 94 } 77 95 … … 84 102 * 85 103 * @return If flags permit it, return NULL, or initialized kernel 86 * call structure .104 * call structure with one reference. 87 105 * 88 106 */ … … 90 108 { 91 109 call_t *call = slab_alloc(ipc_call_slab, flags); 92 if (call) 110 if (call) { 93 111 _ipc_call_init(call); 112 ipc_call_hold(call); 113 } 94 114 95 115 return call; … … 103 123 void ipc_call_free(call_t *call) 104 124 { 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); 109 126 } 110 127 … … 120 137 irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock"); 121 138 waitq_initialize(&box->wq); 122 link_initialize(&box->sync_box_link);123 139 list_initialize(&box->connected_phones); 124 140 list_initialize(&box->calls); … … 134 150 * @param phone Initialized phone structure. 135 151 * @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 */ 154 bool ipc_phone_connect(phone_t *phone, answerbox_t *box) 155 { 156 bool active; 157 140 158 mutex_lock(&phone->lock); 141 142 phone->state = IPC_PHONE_CONNECTED;143 phone->callee = box;144 145 159 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 147 168 irq_spinlock_unlock(&box->lock, true); 148 149 169 mutex_unlock(&phone->lock); 170 171 return active; 150 172 } 151 173 … … 153 175 * 154 176 * @param phone Phone structure to be initialized. 155 * 156 */ 157 void ipc_phone_init(phone_t *phone) 177 * @param caller Owning task. 178 * 179 */ 180 void ipc_phone_init(phone_t *phone, task_t *caller) 158 181 { 159 182 mutex_initialize(&phone->lock, MUTEX_PASSIVE); 183 phone->caller = caller; 160 184 phone->callee = NULL; 161 185 phone->state = IPC_PHONE_FREE; … … 163 187 } 164 188 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 so180 * 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 the198 * 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 208 189 /** Answer a message which was not dispatched and is not listed in any queue. 209 190 * … … 212 193 * 213 194 */ 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 195 void _ipc_answer_free_call(call_t *call, bool selflocked) 196 { 219 197 /* Count sent answer */ 220 198 irq_spinlock_lock(&TASK->lock, true); 221 199 TASK->ipc_info.answer_sent++; 222 200 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)); 223 224 224 225 call->flags |= IPC_CALL_ANSWERED; 225 226 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 233 227 call->data.task_id = TASK->taskid; 234 228 … … 236 230 irq_spinlock_lock(&callerbox->lock, true); 237 231 238 list_append(&call-> link, &callerbox->answers);232 list_append(&call->ab_link, &callerbox->answers); 239 233 240 234 if (do_lock) … … 254 248 /* Remove from active box */ 255 249 irq_spinlock_lock(&box->lock, true); 256 list_remove(&call-> link);250 list_remove(&call->ab_link); 257 251 irq_spinlock_unlock(&box->lock, true); 258 252 259 253 /* Send back answer */ 260 254 _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; 261 272 } 262 273 … … 273 284 void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err) 274 285 { 275 call->data.phone = phone; 276 atomic_inc(&phone->active_calls); 286 _ipc_call_actions_internal(phone, call); 277 287 IPC_SET_RETVAL(call->data, err); 278 288 _ipc_answer_free_call(call, false); … … 288 298 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call) 289 299 { 300 task_t *caller = phone->caller; 301 290 302 /* 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); 300 309 301 310 irq_spinlock_lock(&box->lock, true); 302 list_append(&call-> link, &box->calls);311 list_append(&call->ab_link, &box->calls); 303 312 irq_spinlock_unlock(&box->lock, true); 304 313 … … 320 329 if (phone->state != IPC_PHONE_CONNECTED) { 321 330 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)) { 326 332 if (phone->state == IPC_PHONE_HUNGUP) 327 333 ipc_backsend_err(phone, call, EHANGUP); … … 370 376 call_t *call = ipc_call_alloc(0); 371 377 IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP); 378 call->request_method = IPC_M_PHONE_HUNGUP; 372 379 call->flags |= IPC_CALL_DISCARD_ANSWER; 373 380 _ipc_call(phone, box, call); … … 401 408 TASK->ipc_info.forwarded++; 402 409 irq_spinlock_pass(&TASK->lock, &oldbox->lock); 403 list_remove(&call-> link);410 list_remove(&call->ab_link); 404 411 irq_spinlock_unlock(&oldbox->lock, true); 405 412 406 413 if (mode & IPC_FF_ROUTE_FROM_ME) { 407 if (!call->caller_phone)408 call->caller_phone = call->data.phone;409 414 call->data.phone = newphone; 410 415 call->data.task_id = TASK->taskid; … … 451 456 452 457 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); 455 460 456 461 irq_spinlock_unlock(&box->irq_lock, false); … … 461 466 /* Handle asynchronous answers */ 462 467 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); 466 471 } else if (!list_empty(&box->calls)) { 467 472 /* Count received call */ … … 470 475 /* Handle requests */ 471 476 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); 474 479 475 480 /* Append request to dispatch queue */ 476 list_append(&request-> link, &box->dispatched_calls);481 list_append(&request->ab_link, &box->dispatched_calls); 477 482 } else { 478 483 /* This can happen regularly after ipc_cleanup */ … … 494 499 /** Answer all calls from list with EHANGUP answer. 495 500 * 501 * @param box Answerbox with the list. 496 502 * @param lst Head of the list to be cleaned up. 497 * 498 */ 499 void ipc_cleanup_call_list(list_t *lst) 500 { 503 */ 504 void ipc_cleanup_call_list(answerbox_t *box, list_t *lst) 505 { 506 irq_spinlock_lock(&box->lock, true); 501 507 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; 508 519 IPC_SET_RETVAL(call->data, EHANGUP); 520 answer_preprocess(call, &old); 509 521 _ipc_answer_free_call(call, true); 510 } 522 523 irq_spinlock_lock(&box->lock, true); 524 } 525 irq_spinlock_unlock(&box->lock, true); 511 526 } 512 527 … … 546 561 mutex_unlock(&phone->lock); 547 562 irq_spinlock_unlock(&box->lock, true); 548 563 564 // FIXME: phone can become deallocated at any time now 565 549 566 /* 550 567 * Send one message to the answerbox for each … … 554 571 */ 555 572 IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP); 573 call->request_method = IPC_M_PHONE_HUNGUP; 556 574 call->flags |= IPC_CALL_DISCARD_ANSWER; 557 575 _ipc_call(phone, box, call); … … 574 592 } 575 593 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 576 717 /** Clean up all IPC communication of the current task. 577 718 * … … 582 723 void ipc_cleanup(void) 583 724 { 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 584 735 /* 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++) 587 737 ipc_phone_hangup(&TASK->phones[i]); 588 738 … … 602 752 603 753 /* 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(); 665 760 } 666 761 … … 670 765 void ipc_init(void) 671 766 { 672 ipc_call_slab = slab_cache_create(" ipc_call", sizeof(call_t), 0, NULL,767 ipc_call_slab = slab_cache_create("call_t", sizeof(call_t), 0, NULL, 673 768 NULL, 0); 674 ipc_answerbox_slab = slab_cache_create(" ipc_answerbox",769 ipc_answerbox_slab = slab_cache_create("answerbox_t", 675 770 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 } 676 805 } 677 806 … … 747 876 748 877 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); 768 879 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); 788 881 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); 807 883 808 884 irq_spinlock_unlock(&task->answerbox.lock, false);
Note:
See TracChangeset
for help on using the changeset viewer.