Changes in kernel/generic/src/ipc/ipc.c [a35b458:1b20da0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
ra35b458 r1b20da0 127 127 kobject_initialize(kobj, KOBJECT_TYPE_CALL, call, &call_kobject_ops); 128 128 call->kobject = kobj; 129 129 130 130 return call; 131 131 } … … 212 212 answerbox_t *mybox = slab_alloc(answerbox_cache, 0); 213 213 ipc_answerbox_init(mybox, TASK); 214 214 215 215 /* We will receive data in a special box. */ 216 216 request->callerbox = mybox; 217 217 218 218 errno_t rc = ipc_call(phone, request); 219 219 if (rc != EOK) { … … 247 247 ipc_forget_call(request); /* releases locks */ 248 248 rc = EINTR; 249 249 250 250 } else { 251 251 spinlock_unlock(&TASK->active_calls_lock); … … 264 264 } 265 265 assert(!answer || request == answer); 266 266 267 267 slab_free(answerbox_cache, mybox); 268 268 return rc; … … 305 305 &call->sender->answerbox; 306 306 bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox)); 307 307 308 308 call->flags |= IPC_CALL_ANSWERED; 309 309 310 310 call->data.task_id = TASK->taskid; 311 311 312 312 if (do_lock) 313 313 irq_spinlock_lock(&callerbox->lock, true); 314 314 315 315 list_append(&call->ab_link, &callerbox->answers); 316 316 317 317 if (do_lock) 318 318 irq_spinlock_unlock(&callerbox->lock, true); 319 319 320 320 waitq_wakeup(&callerbox->wq, WAKEUP_FIRST); 321 321 } … … 333 333 list_remove(&call->ab_link); 334 334 irq_spinlock_unlock(&box->lock, true); 335 335 336 336 /* Send back answer */ 337 337 _ipc_answer_free_call(call, false); … … 395 395 caller->ipc_info.call_sent++; 396 396 irq_spinlock_unlock(&caller->lock, true); 397 397 398 398 if (!(call->flags & IPC_CALL_FORWARDED)) 399 399 _ipc_call_actions_internal(phone, call, preforget); 400 400 401 401 irq_spinlock_lock(&box->lock, true); 402 402 list_append(&call->ab_link, &box->calls); 403 403 irq_spinlock_unlock(&box->lock, true); 404 404 405 405 waitq_wakeup(&box->wq, WAKEUP_FIRST); 406 406 } … … 426 426 ipc_backsend_err(phone, call, ENOENT); 427 427 } 428 428 429 429 return ENOENT; 430 430 } 431 431 432 432 answerbox_t *box = phone->callee; 433 433 _ipc_call(phone, box, call, false); 434 434 435 435 mutex_unlock(&phone->lock); 436 436 return 0; … … 457 457 return EINVAL; 458 458 } 459 459 460 460 answerbox_t *box = phone->callee; 461 461 if (phone->state != IPC_PHONE_SLAMMED) { … … 467 467 /* Drop the answerbox reference */ 468 468 kobject_put(phone->kobject); 469 469 470 470 call_t *call = ipc_call_alloc(0); 471 471 IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP); … … 474 474 _ipc_call(phone, box, call, false); 475 475 } 476 476 477 477 phone->state = IPC_PHONE_HUNGUP; 478 478 mutex_unlock(&phone->lock); 479 479 480 480 return EOK; 481 481 } … … 504 504 list_remove(&call->ab_link); 505 505 irq_spinlock_unlock(&oldbox->lock, true); 506 506 507 507 if (mode & IPC_FF_ROUTE_FROM_ME) { 508 508 call->data.phone = newphone; 509 509 call->data.task_id = TASK->taskid; 510 510 } 511 511 512 512 return ipc_call(newphone, call); 513 513 } … … 536 536 uint64_t call_cnt = 0; 537 537 errno_t rc; 538 538 539 539 restart: 540 540 rc = waitq_sleep_timeout(&box->wq, usec, flags, NULL); 541 541 if (rc != EOK) 542 542 return NULL; 543 543 544 544 irq_spinlock_lock(&box->lock, true); 545 545 if (!list_empty(&box->irq_notifs)) { 546 546 /* Count received IRQ notification */ 547 547 irq_cnt++; 548 548 549 549 irq_spinlock_lock(&box->irq_lock, false); 550 550 551 551 request = list_get_instance(list_first(&box->irq_notifs), 552 552 call_t, ab_link); 553 553 list_remove(&request->ab_link); 554 554 555 555 irq_spinlock_unlock(&box->irq_lock, false); 556 556 } else if (!list_empty(&box->answers)) { 557 557 /* Count received answer */ 558 558 answer_cnt++; 559 559 560 560 /* Handle asynchronous answers */ 561 561 request = list_get_instance(list_first(&box->answers), … … 566 566 /* Count received call */ 567 567 call_cnt++; 568 568 569 569 /* Handle requests */ 570 570 request = list_get_instance(list_first(&box->calls), 571 571 call_t, ab_link); 572 572 list_remove(&request->ab_link); 573 573 574 574 /* Append request to dispatch queue */ 575 575 list_append(&request->ab_link, &box->dispatched_calls); … … 579 579 goto restart; 580 580 } 581 581 582 582 irq_spinlock_pass(&box->lock, &TASK->lock); 583 583 584 584 TASK->ipc_info.irq_notif_received += irq_cnt; 585 585 TASK->ipc_info.answer_received += answer_cnt; 586 586 TASK->ipc_info.call_received += call_cnt; 587 587 588 588 irq_spinlock_unlock(&TASK->lock, true); 589 589 590 590 return request; 591 591 } … … 602 602 call_t *call = list_get_instance(list_first(lst), call_t, 603 603 ab_link); 604 604 605 605 list_remove(&call->ab_link); 606 606 … … 631 631 phone_t *phone; 632 632 DEADLOCK_PROBE_INIT(p_phonelck); 633 633 634 634 /* Disconnect all phones connected to our answerbox */ 635 635 restart_phones: … … 643 643 goto restart_phones; 644 644 } 645 645 646 646 /* Disconnect phone */ 647 647 assert(phone->state == IPC_PHONE_CONNECTED); 648 648 649 649 list_remove(&phone->link); 650 650 phone->state = IPC_PHONE_SLAMMED; 651 651 652 652 if (notify_box) { 653 653 task_hold(phone->caller); … … 671 671 672 672 kobject_put(phone->kobject); 673 673 674 674 /* Must start again */ 675 675 goto restart_phones; 676 676 } 677 677 678 678 mutex_unlock(&phone->lock); 679 679 kobject_put(phone->kobject); 680 680 } 681 681 682 682 irq_spinlock_unlock(&box->lock, true); 683 683 } … … 727 727 return; 728 728 } 729 729 730 730 call = list_get_instance(list_first(&TASK->active_calls), call_t, 731 731 ta_link); … … 811 811 if (restart) 812 812 goto restart; 813 813 814 814 call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT, 815 815 SYNCH_FLAGS_NONE); … … 872 872 caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_PHONE, 873 873 phone_cap_cleanup_cb, NULL); 874 874 875 875 /* Unsubscribe from any event notifications. */ 876 876 event_cleanup_answerbox(&TASK->answerbox); 877 877 878 878 /* Disconnect all connected IRQs */ 879 879 caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_IRQ, irq_cap_cleanup_cb, 880 880 NULL); 881 881 882 882 /* Disconnect all phones connected to our regular answerbox */ 883 883 ipc_answerbox_slam_phones(&TASK->answerbox, false); 884 884 885 885 #ifdef CONFIG_UDEBUG 886 886 /* Clean up kbox thread and communications */ … … 891 891 caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_CALL, call_cap_cleanup_cb, 892 892 NULL); 893 893 894 894 /* Answer all messages in 'calls' and 'dispatched_calls' queues */ 895 895 ipc_cleanup_call_list(&TASK->answerbox, &TASK->answerbox.calls); 896 896 ipc_cleanup_call_list(&TASK->answerbox, 897 897 &TASK->answerbox.dispatched_calls); 898 898 899 899 ipc_forget_all_active_calls(); 900 900 ipc_wait_for_all_answered_calls(); … … 921 921 printf("%10p ", call); 922 922 #endif 923 923 924 924 #ifdef __64_BITS__ 925 925 printf("%18p ", call); 926 926 #endif 927 927 928 928 spinlock_lock(&call->forget_lock); 929 929 … … 954 954 printf("%-11d %7" PRIun " ", cap->handle, 955 955 atomic_get(&phone->active_calls)); 956 956 957 957 switch (phone->state) { 958 958 case IPC_PHONE_CONNECTING: … … 973 973 break; 974 974 } 975 975 976 976 printf("\n"); 977 977 } … … 996 996 task_hold(task); 997 997 irq_spinlock_unlock(&tasks_lock, true); 998 998 999 999 printf("[phone cap] [calls] [state\n"); 1000 1000 1001 1001 caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE, 1002 1002 print_task_phone_cb, NULL); 1003 1003 1004 1004 irq_spinlock_lock(&task->lock, true); 1005 1005 irq_spinlock_lock(&task->answerbox.lock, false); 1006 1006 1007 1007 #ifdef __32_BITS__ 1008 1008 printf("[call id ] [method] [arg1] [arg2] [arg3] [arg4] [arg5]" 1009 1009 " [flags] [sender\n"); 1010 1010 #endif 1011 1011 1012 1012 #ifdef __64_BITS__ 1013 1013 printf("[call id ] [method] [arg1] [arg2] [arg3] [arg4]" 1014 1014 " [arg5] [flags] [sender\n"); 1015 1015 #endif 1016 1016 1017 1017 printf(" --- incomming calls ---\n"); 1018 1018 ipc_print_call_list(&task->answerbox.calls); … … 1021 1021 printf(" --- incoming answers ---\n"); 1022 1022 ipc_print_call_list(&task->answerbox.answers); 1023 1023 1024 1024 irq_spinlock_unlock(&task->answerbox.lock, false); 1025 1025 irq_spinlock_unlock(&task->lock, true);
Note:
See TracChangeset
for help on using the changeset viewer.