Ignore:
File:
1 edited

Legend:

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

    re701eb1 r287e83f  
    6262
    6363static slab_cache_t *ipc_call_slab;
    64 static slab_cache_t *ipc_answerbox_slab;
    6564
    6665/** Initialize a call structure.
     
    9796}
    9897
     98/** Initialize a statically allocated call structure.
     99 *
     100 * @param call          Statically allocated kernel call structure to be
     101 *                      initialized.
     102 */
     103void ipc_call_static_init(call_t *call)
     104{
     105        _ipc_call_init(call);
     106        call->flags |= IPC_CALL_STATIC_ALLOC;
     107}
     108
    99109/** Deallocate a call structure.
    100110 *
     
    103113void ipc_call_free(call_t *call)
    104114{
     115        ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
    105116        /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
    106117        if (call->buffer)
     
    119130        spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
    120131        waitq_initialize(&box->wq);
    121         link_initialize(&box->sync_box_link);
    122132        list_initialize(&box->connected_phones);
    123133        list_initialize(&box->calls);
     
    169179int ipc_call_sync(phone_t *phone, call_t *request)
    170180{
    171         answerbox_t *sync_box;
    172         ipl_t ipl;
    173 
    174         sync_box = slab_alloc(ipc_answerbox_slab, 0);
    175         ipc_answerbox_init(sync_box, TASK);
    176 
    177         /*
    178          * Put the answerbox on the TASK's list of synchronous answerboxes so
    179          * that it can be cleaned up if the call is interrupted.
    180          */
    181         ipl = interrupts_disable();
    182         spinlock_lock(&TASK->lock);
    183         list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
    184         spinlock_unlock(&TASK->lock);
    185         interrupts_restore(ipl);
     181        answerbox_t sync_box;
     182
     183        ipc_answerbox_init(&sync_box, TASK);
    186184
    187185        /* We will receive data in a special box. */
    188         request->callerbox = sync_box;
     186        request->callerbox = &sync_box;
    189187
    190188        ipc_call(phone, request);
    191         if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
    192             SYNCH_FLAGS_INTERRUPTIBLE)) {
    193                 /* The answerbox and the call will be freed by ipc_cleanup(). */
     189        if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
     190            SYNCH_FLAGS_INTERRUPTIBLE))
    194191                return EINTR;
    195         }
    196 
    197         /*
    198          * The answer arrived without interruption so we can remove the
    199          * answerbox from the TASK's list of synchronous answerboxes.
    200          */
    201         (void) interrupts_disable();
    202         spinlock_lock(&TASK->lock);
    203         list_remove(&sync_box->sync_box_link);
    204         spinlock_unlock(&TASK->lock);
    205         interrupts_restore(ipl);
    206 
    207         slab_free(ipc_answerbox_slab, sync_box);
    208192        return EOK;
    209193}
     
    536520        int i;
    537521        call_t *call;
    538         ipl_t ipl;
    539522
    540523        /* Disconnect all our phones ('ipc_phone_hangup') */
     
    562545        spinlock_unlock(&TASK->answerbox.lock);
    563546       
    564         /* Wait for all answers to interrupted synchronous calls to arrive */
    565         ipl = interrupts_disable();
    566         while (!list_empty(&TASK->sync_box_head)) {
    567                 answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
    568                     answerbox_t, sync_box_link);
    569 
    570                 list_remove(&box->sync_box_link);
    571                 call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
    572                     SYNCH_FLAGS_NONE);
    573                 ipc_call_free(call);
    574                 slab_free(ipc_answerbox_slab, box);
    575         }
    576         interrupts_restore(ipl);
    577 
    578         /* Wait for all answers to asynchronous calls to arrive */
     547        /* Wait for all async answers to arrive */
    579548        while (1) {
    580549                /* Go through all phones, until all are FREE... */
     
    583552                for (i = 0; i < IPC_MAX_PHONES; i++) {
    584553                        if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
    585                             atomic_get(&TASK->phones[i].active_calls) == 0) {
     554                            atomic_get(&TASK->phones[i].active_calls) == 0)
    586555                                TASK->phones[i].state = IPC_PHONE_FREE;
    587                                 TASK->phones[i].callee = NULL;
    588                         }
    589556                       
    590557                        /* Just for sure, we might have had some
     
    607574                ASSERT((call->flags & IPC_CALL_ANSWERED) ||
    608575                    (call->flags & IPC_CALL_NOTIF));
     576                ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
    609577               
    610578                /*
     
    625593        ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
    626594            NULL, 0);
    627         ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
    628             sizeof(answerbox_t), 0, NULL, NULL, 0);
    629595}
    630596
Note: See TracChangeset for help on using the changeset viewer.