Ignore:
File:
1 edited

Legend:

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

    r82d515e9 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
     
    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 {
     
    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.