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


Ignore:
Timestamp:
2008-09-17T12:16:27Z (17 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.

Location:
kernel/generic/src/ipc
Files:
1 added
2 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);
  • kernel/generic/src/ipc/sysipc.c

    r06a195bc r9a1b20c  
    4343#include <ipc/irq.h>
    4444#include <ipc/ipcrsc.h>
     45#include <ipc/ipc_kbox.h>
     46#include <udebug/udebug_ipc.h>
    4547#include <arch/interrupt.h>
    4648#include <print.h>
     
    296298 *
    297299 * @param call          Call structure with the request.
     300 * @param phone         Phone that the call will be sent through.
    298301 *
    299302 * @return              Return 0 on success, ELIMIT or EPERM on error.
    300303 */
    301 static int request_preprocess(call_t *call)
     304static int request_preprocess(call_t *call, phone_t *phone)
    302305{
    303306        int newphid;
     
    341344                }
    342345                break;
     346#ifdef CONFIG_UDEBUG
     347        case IPC_M_DEBUG_ALL:
     348                return udebug_request_preprocess(call, phone);
     349#endif
    343350        default:
    344351                break;
     
    370377        if (call->buffer) {
    371378                /* This must be an affirmative answer to IPC_M_DATA_READ. */
     379                /* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */
    372380                uintptr_t dst = IPC_GET_ARG1(call->data);
    373381                size_t size = IPC_GET_ARG2(call->data);
     
    400408                }
    401409                IPC_SET_ARG5(call->data, phoneid);
    402         }
     410        }
     411        switch (IPC_GET_METHOD(call->data)) {
     412        case IPC_M_DEBUG_ALL:
     413                return -1;
     414        default:
     415                break;
     416        }
    403417        return 0;
    404418}
     
    442456        IPC_SET_ARG5(call.data, 0);
    443457
    444         if (!(res = request_preprocess(&call))) {
     458        if (!(res = request_preprocess(&call, phone))) {
    445459                rc = ipc_call_sync(phone, &call);
    446460                if (rc != EOK)
     
    482496        GET_CHECK_PHONE(phone, phoneid, return ENOENT);
    483497
    484         if (!(res = request_preprocess(&call))) {
     498        if (!(res = request_preprocess(&call, phone))) {
    485499                rc = ipc_call_sync(phone, &call);
    486500                if (rc != EOK)
     
    551565        IPC_SET_ARG5(call->data, 0);
    552566
    553         if (!(res = request_preprocess(call)))
     567        if (!(res = request_preprocess(call, phone)))
    554568                ipc_call(phone, call);
    555569        else
     
    585599                return (unative_t) rc;
    586600        }
    587         if (!(res = request_preprocess(call)))
     601        if (!(res = request_preprocess(call, phone)))
    588602                ipc_call(phone, call);
    589603        else
     
    869883}
    870884
     885#include <console/console.h>
     886
     887/**
     888 * Syscall connect to a task by id.
     889 *
     890 * @return              Phone id on success, or negative error code.
     891 */
     892unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg)
     893{
     894#ifdef CONFIG_UDEBUG
     895        sysarg64_t taskid_arg;
     896        int rc;
     897       
     898        rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
     899        if (rc != 0)
     900                return (unative_t) rc;
     901
     902        printf("sys_ipc_connect_kbox(%lld, %d)\n", taskid_arg.value);
     903
     904        return ipc_connect_kbox(taskid_arg.value);
     905#else
     906        return (unative_t) ENOTSUP;
     907#endif
     908}
     909
    871910/** @}
    872911 */
Note: See TracChangeset for help on using the changeset viewer.