Changeset 9a1b20c in mainline for kernel/generic/src/ipc/ipc.c


Ignore:
Timestamp:
2008-09-17T12:16:27Z (16 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb9b0b0
Parents:
06a195bc
Message:

Merge syscall tracer (trace) and relevant part of udebug interface from tracing to trunk.

File:
1 edited

Legend:

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

    r06a195bc r9a1b20c  
    4444#include <synch/synch.h>
    4545#include <ipc/ipc.h>
     46#include <ipc/ipc_kbox.h>
    4647#include <errno.h>
    4748#include <mm/slab.h>
     
    5253
    5354#include <print.h>
     55#include <console/console.h>
    5456#include <proc/thread.h>
    5557#include <arch/interrupt.h>
     
    428430 * @param lst           Head of the list to be cleaned up.
    429431 */
    430 static void ipc_cleanup_call_list(link_t *lst)
     432void ipc_cleanup_call_list(link_t *lst)
    431433{
    432434        call_t *call;
     
    443445}
    444446
     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 */
     453void 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 */
     463restart_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
    445514/** Cleans up all IPC communication of the current task.
    446515 *
     
    452521        int i;
    453522        call_t *call;
    454         phone_t *phone;
    455         DEADLOCK_PROBE_INIT(p_phonelck);
    456523
    457524        /* Disconnect all our phones ('ipc_phone_hangup') */
     
    462529        ipc_irq_cleanup(&TASK->answerbox);
    463530
    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 */
    466540        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 */
    485541        ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
    486542        ipc_cleanup_call_list(&TASK->answerbox.calls);
Note: See TracChangeset for help on using the changeset viewer.