Changeset ca687ad in mainline


Ignore:
Timestamp:
2006-03-31T13:53:36Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0cb56f5d
Parents:
296cc1b
Message:

Completed ipc_cleanup, it should be somehow integrated into
cleanup of task. The function can sleep.

Location:
generic/src/ipc
Files:
3 edited

Legend:

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

    r296cc1b rca687ad  
    323323                list_append(&request->list, &box->dispatched_calls);
    324324        } else {
     325                /* This can happen regularly after ipc_cleanup, remove
     326                 * the warning in the future when the IPC is
     327                 * more debugged */
    325328                printf("WARNING: Spurious IPC wakeup.\n");
    326329                spinlock_unlock(&box->lock);
     
    340343}
    341344
     345/** Answer all calls from list with EHANGUP msg */
     346static void ipc_cleanup_call_list(link_t *lst)
     347{
     348        call_t *call;
     349
     350        while (!list_empty(lst)) {
     351                call = list_get_instance(lst->next, call_t, list);
     352                list_remove(&call->list);
     353
     354                IPC_SET_RETVAL(call->data, EHANGUP);
     355                _ipc_answer_free_call(call);
     356        }
     357}
     358
    342359/** Cleans up all IPC communication of the given task
    343360 *
     
    347364{
    348365        int i;
    349 
     366        call_t *call;
     367        phone_t *phone;
     368       
    350369        /* Disconnect all our phones ('ipc_phone_hangup') */
    351370        for (i=0;i < IPC_MAX_PHONES; i++)
    352371                ipc_phone_hangup(&task->phones[i]);
    353372
    354         /* Disconnect all phones connected to answerbox */
     373        /* Disconnect all phones connected to our answerbox */
     374restart_phones:
     375        spinlock_lock(&task->answerbox.lock);
     376        while (!list_empty(&task->answerbox.connected_phones)) {
     377                phone = list_get_instance(task->answerbox.connected_phones.next,
     378                                          phone_t,
     379                                          list);
     380                if (! spinlock_trylock(&phone->lock)) {
     381                        spinlock_unlock(&task->answerbox.lock);
     382                        goto restart_phones;
     383                }
     384               
     385                /* Disconnect phone */
     386                phone->callee = NULL;
     387                list_remove(&phone->list);
     388
     389                spinlock_unlock(&phone->lock);
     390        }
    355391
    356392        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
     393        spinlock_lock(&task->answerbox.lock);
     394        ipc_cleanup_call_list(&task->answerbox.dispatched_calls);
     395        ipc_cleanup_call_list(&task->answerbox.calls);
     396        spinlock_unlock(&task->answerbox.lock);
    357397       
    358398        /* Wait for all async answers to arrive */
    359 }
     399        while (atomic_get(&task->active_calls)) {
     400                call = ipc_wait_for_call(&task->answerbox, 0);
     401                ASSERT(call->flags & IPC_CALL_ANSWERED);
     402                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
     403               
     404                atomic_dec(&task->active_calls);
     405                ipc_call_free(call);
     406        }
     407}
  • generic/src/ipc/ipcrsc.c

    r296cc1b rca687ad  
    130130/** Find call_t * in call table according to callid
    131131 *
     132 * TODO: Some speedup (hash table?)
    132133 * @return NULL on not found, otherwise pointer to call structure
    133134 */
    134135call_t * get_call(__native callid)
    135136{
    136         /* TODO: Traverse list of dispatched calls and find one */
    137         /* TODO: locking of call, ripping it from dispatched calls etc.  */
    138         return (call_t *) callid;
     137        link_t *lst;
     138        call_t *call, *result = NULL;
     139
     140        spinlock_lock(&TASK->answerbox.lock);
     141        for (lst = TASK->answerbox.dispatched_calls.next;
     142             lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
     143                call = list_get_instance(lst, call_t, list);
     144                if ((__native)call == callid) {
     145                        result = call;
     146                        break;
     147                }
     148        }
     149        spinlock_unlock(&TASK->answerbox.lock);
     150        return result;
    139151}
    140152
  • generic/src/ipc/sysipc.c

    r296cc1b rca687ad  
    9393
    9494        if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
    95                 /* Atomic operation */
    96                 answer->data.phone->callee = NULL;
     95                /* In case of forward, hangup the forwared phone,
     96                 * not the originator
     97                 */
     98                spinlock_lock(&answer->data.phone->lock);
     99                spinlock_lock(&TASK->answerbox.lock);
     100                if (answer->data.phone->callee) {
     101                        list_remove(&answer->data.phone->list);
     102                        answer->data.phone->callee = 0;
     103                }
     104                spinlock_unlock(&TASK->answerbox.lock);
     105                spinlock_unlock(&answer->data.phone->lock);
    97106        }
    98107
Note: See TracChangeset for help on using the changeset viewer.