Changeset 9a1b20c in mainline for kernel/generic/src/ipc/ipc.c
- Timestamp:
- 2008-09-17T12:16:27Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fb9b0b0
- Parents:
- 06a195bc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/ipc.c
r06a195bc r9a1b20c 44 44 #include <synch/synch.h> 45 45 #include <ipc/ipc.h> 46 #include <ipc/ipc_kbox.h> 46 47 #include <errno.h> 47 48 #include <mm/slab.h> … … 52 53 53 54 #include <print.h> 55 #include <console/console.h> 54 56 #include <proc/thread.h> 55 57 #include <arch/interrupt.h> … … 428 430 * @param lst Head of the list to be cleaned up. 429 431 */ 430 staticvoid ipc_cleanup_call_list(link_t *lst)432 void ipc_cleanup_call_list(link_t *lst) 431 433 { 432 434 call_t *call; … … 443 445 } 444 446 447 /** Disconnects all phones connected to an answerbox. 448 * 449 * @param box Answerbox to disconnect phones from. 450 * @param notify_box If true, the answerbox will get a hangup message for 451 * each disconnected phone. 452 */ 453 void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box) 454 { 455 phone_t *phone; 456 DEADLOCK_PROBE_INIT(p_phonelck); 457 ipl_t ipl; 458 call_t *call; 459 460 call = notify_box ? ipc_call_alloc(0) : NULL; 461 462 /* Disconnect all phones connected to our answerbox */ 463 restart_phones: 464 ipl = interrupts_disable(); 465 spinlock_lock(&box->lock); 466 while (!list_empty(&box->connected_phones)) { 467 phone = list_get_instance(box->connected_phones.next, 468 phone_t, link); 469 if (SYNCH_FAILED(mutex_trylock(&phone->lock))) { 470 spinlock_unlock(&box->lock); 471 interrupts_restore(ipl); 472 DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD); 473 goto restart_phones; 474 } 475 476 /* Disconnect phone */ 477 ASSERT(phone->state == IPC_PHONE_CONNECTED); 478 479 list_remove(&phone->link); 480 phone->state = IPC_PHONE_SLAMMED; 481 482 if (notify_box) { 483 mutex_unlock(&phone->lock); 484 spinlock_unlock(&box->lock); 485 interrupts_restore(ipl); 486 487 /* 488 * Send one message to the answerbox for each 489 * phone. Used to make sure the kbox thread 490 * wakes up after the last phone has been 491 * disconnected. 492 */ 493 IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP); 494 call->flags |= IPC_CALL_DISCARD_ANSWER; 495 _ipc_call(phone, box, call); 496 497 /* Allocate another call in advance */ 498 call = ipc_call_alloc(0); 499 500 /* Must start again */ 501 goto restart_phones; 502 } 503 504 mutex_unlock(&phone->lock); 505 } 506 507 spinlock_unlock(&box->lock); 508 interrupts_restore(ipl); 509 510 /* Free unused call */ 511 if (call) ipc_call_free(call); 512 } 513 445 514 /** Cleans up all IPC communication of the current task. 446 515 * … … 452 521 int i; 453 522 call_t *call; 454 phone_t *phone;455 DEADLOCK_PROBE_INIT(p_phonelck);456 523 457 524 /* Disconnect all our phones ('ipc_phone_hangup') */ … … 462 529 ipc_irq_cleanup(&TASK->answerbox); 463 530 464 /* Disconnect all phones connected to our answerbox */ 465 restart_phones: 531 /* Disconnect all phones connected to our regular answerbox */ 532 ipc_answerbox_slam_phones(&TASK->answerbox, false); 533 534 #ifdef CONFIG_UDEBUG 535 /* Clean up kbox thread and communications */ 536 ipc_kbox_cleanup(); 537 #endif 538 539 /* Answer all messages in 'calls' and 'dispatched_calls' queues */ 466 540 spinlock_lock(&TASK->answerbox.lock); 467 while (!list_empty(&TASK->answerbox.connected_phones)) {468 phone = list_get_instance(TASK->answerbox.connected_phones.next,469 phone_t, link);470 if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {471 spinlock_unlock(&TASK->answerbox.lock);472 DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);473 goto restart_phones;474 }475 476 /* Disconnect phone */477 ASSERT(phone->state == IPC_PHONE_CONNECTED);478 phone->state = IPC_PHONE_SLAMMED;479 list_remove(&phone->link);480 481 mutex_unlock(&phone->lock);482 }483 484 /* Answer all messages in 'calls' and 'dispatched_calls' queues */485 541 ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls); 486 542 ipc_cleanup_call_list(&TASK->answerbox.calls);
Note:
See TracChangeset
for help on using the changeset viewer.