Ignore:
File:
1 edited

Legend:

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

    rcde999a rc1f68b0  
    6666answerbox_t *ipc_phone_0 = NULL;
    6767
    68 static slab_cache_t *call_cache;
    69 static slab_cache_t *answerbox_cache;
    70 
    71 slab_cache_t *phone_cache = NULL;
     68static slab_cache_t *call_slab;
     69static slab_cache_t *answerbox_slab;
     70
     71slab_cache_t *phone_slab = NULL;
    7272
    7373/** Initialize a call structure.
     
    8787}
    8888
    89 static void call_destroy(void *arg)
    90 {
    91         call_t *call = (call_t *) arg;
    92 
    93         if (call->buffer)
    94                 free(call->buffer);
    95         if (call->caller_phone)
    96                 kobject_put(call->caller_phone->kobject);
    97         slab_free(call_cache, call);
    98 }
    99 
    100 static kobject_ops_t call_kobject_ops = {
    101         .destroy = call_destroy
    102 };
     89void ipc_call_hold(call_t *call)
     90{
     91        atomic_inc(&call->refcnt);
     92}
     93
     94void ipc_call_release(call_t *call)
     95{
     96        if (atomic_predec(&call->refcnt) == 0) {
     97                if (call->buffer)
     98                        free(call->buffer);
     99                if (call->caller_phone)
     100                        kobject_put(call->caller_phone->kobject);
     101                slab_free(call_slab, call);
     102        }
     103}
    103104
    104105/** Allocate and initialize a call structure.
     
    115116call_t *ipc_call_alloc(unsigned int flags)
    116117{
    117         call_t *call = slab_alloc(call_cache, flags);
    118         if (!call)
    119                 return NULL;
    120         kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t), flags);
    121         if (!kobj) {
    122                 slab_free(call_cache, call);
    123                 return NULL;
    124         }
    125 
    126         _ipc_call_init(call);
    127         kobject_initialize(kobj, KOBJECT_TYPE_CALL, call, &call_kobject_ops);
    128         call->kobject = kobj;
     118        call_t *call = slab_alloc(call_slab, flags);
     119        if (call) {
     120                _ipc_call_init(call);
     121                ipc_call_hold(call);
     122        }
    129123       
    130124        return call;
     125}
     126
     127/** Deallocate a call structure.
     128 *
     129 * @param call Call structure to be freed.
     130 *
     131 */
     132void ipc_call_free(call_t *call)
     133{
     134        ipc_call_release(call);
    131135}
    132136
     
    205209 * @param request Call structure with request.
    206210 *
    207  * @return EOK on success or an error code.
     211 * @return EOK on success or a negative error code.
    208212 *
    209213 */
    210214int ipc_call_sync(phone_t *phone, call_t *request)
    211215{
    212         answerbox_t *mybox = slab_alloc(answerbox_cache, 0);
     216        answerbox_t *mybox = slab_alloc(answerbox_slab, 0);
    213217        ipc_answerbox_init(mybox, TASK);
    214218       
     
    218222        int rc = ipc_call(phone, request);
    219223        if (rc != EOK) {
    220                 slab_free(answerbox_cache, mybox);
     224                slab_free(answerbox_slab, mybox);
    221225                return rc;
    222226        }
     
    265269        assert(!answer || request == answer);
    266270       
    267         slab_free(answerbox_cache, mybox);
     271        slab_free(answerbox_slab, mybox);
    268272        return rc;
    269273}
     
    286290                /* This is a forgotten call and call->sender is not valid. */
    287291                spinlock_unlock(&call->forget_lock);
    288                 kobject_put(call->kobject);
     292                ipc_call_free(call);
    289293                return;
    290294        } else {
     
    371375 *
    372376 */
    373 void ipc_backsend_err(phone_t *phone, call_t *call, int err)
     377void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err)
    374378{
    375379        _ipc_call_actions_internal(phone, call, false);
     
    444448 * @param phone Phone structure to be hung up.
    445449 *
    446  * @return EOK if the phone is disconnected.
    447  * @return EINVAL if the phone was already disconnected.
     450 * @return 0 if the phone is disconnected.
     451 * @return -1 if the phone was already disconnected.
    448452 *
    449453 */
     
    455459            phone->state == IPC_PHONE_CONNECTING) {
    456460                mutex_unlock(&phone->lock);
    457                 return EINVAL;
     461                return -1;
    458462        }
    459463       
     
    478482        mutex_unlock(&phone->lock);
    479483       
    480         return EOK;
     484        return 0;
    481485}
    482486
     
    538542       
    539543restart:
    540         rc = waitq_sleep_timeout(&box->wq, usec, flags, NULL);
    541         if (rc != EOK)
     544        rc = waitq_sleep_timeout(&box->wq, usec, flags);
     545        if (SYNCH_FAILED(rc))
    542546                return NULL;
    543547       
     
    638642                phone = list_get_instance(list_first(&box->connected_phones),
    639643                    phone_t, link);
    640                 if (mutex_trylock(&phone->lock) != EOK) {
     644                if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
    641645                        irq_spinlock_unlock(&box->lock, true);
    642646                        DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
     
    701705         * must hold a reference to it.
    702706         */
    703         kobject_add_ref(call->kobject);
     707        ipc_call_hold(call);
    704708
    705709        spinlock_unlock(&call->forget_lock);
     
    710714        SYSIPC_OP(request_forget, call);
    711715
    712         kobject_put(call->kobject);
     716        ipc_call_release(call);
    713717}
    714718
     
    818822        SYSIPC_OP(answer_process, call);
    819823
    820         kobject_put(call->kobject);
     824        ipc_call_free(call);
    821825        goto restart;
    822826}
     
    835839{
    836840        ipc_irq_unsubscribe(&TASK->answerbox, cap->handle);
    837         return true;
    838 }
    839 
    840 static bool call_cap_cleanup_cb(cap_t *cap, void *arg)
    841 {
    842         /*
    843          * Here we just free the capability and release the kobject.
    844          * The kernel answers the remaining calls elsewhere in ipc_cleanup().
    845          */
    846         kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
    847             KOBJECT_TYPE_CALL);
    848         kobject_put(kobj);
    849         cap_free(cap->task, cap->handle);
    850841        return true;
    851842}
     
    887878        ipc_kbox_cleanup();
    888879#endif
    889 
    890         /* Destroy all call capabilities */
    891         caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_CALL, call_cap_cleanup_cb,
    892             NULL);
    893880       
    894881        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
     
    906893void ipc_init(void)
    907894{
    908         call_cache = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
     895        call_slab = slab_cache_create("call_t", sizeof(call_t), 0, NULL,
    909896            NULL, 0);
    910         phone_cache = slab_cache_create("phone_t", sizeof(phone_t), 0, NULL,
     897        phone_slab = slab_cache_create("phone_t", sizeof(phone_t), 0, NULL,
    911898            NULL, 0);
    912         answerbox_cache = slab_cache_create("answerbox_t", sizeof(answerbox_t),
     899        answerbox_slab = slab_cache_create("answerbox_t", sizeof(answerbox_t),
    913900            0, NULL, NULL, 0);
    914901}
Note: See TracChangeset for help on using the changeset viewer.