Changeset cd671c3 in mainline


Ignore:
Timestamp:
2012-09-05T22:36:48Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1d5ef8
Parents:
239acce
Message:

Reference count call_t structures.
Add ipc_call_hold() and ipc_call_release().
Hold the forgotten call during the request_forget() callback.

Location:
kernel/generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    r239acce rcd671c3  
    116116        link_t ta_link;
    117117
     118        atomic_t refcnt;
     119
    118120        /** Answerbox link. */
    119121        link_t ab_link;
     
    166168extern call_t *ipc_call_alloc(unsigned int);
    167169extern void ipc_call_free(call_t *);
     170extern void ipc_call_hold(call_t *);
     171extern void ipc_call_release(call_t *);
    168172
    169173extern int ipc_call(phone_t *, call_t *);
  • kernel/generic/include/ipc/sysipc_ops.h

    r239acce rcd671c3  
    5555         * Context:             caller
    5656         * Caller alive:        guaranteed
    57          * Races with:          request_process(), answer_cleanup()
     57         * Races with:          request_process(), answer_cleanup(),
     58         *                      _ipc_answer_free_call()
    5859         * Invoked on:          all forgotten calls
    5960         */     
  • kernel/generic/src/ipc/ipc.c

    r239acce rcd671c3  
    8080}
    8181
     82void ipc_call_hold(call_t *call)
     83{
     84        atomic_inc(&call->refcnt);
     85}
     86
     87void ipc_call_release(call_t *call)
     88{
     89        if (atomic_predec(&call->refcnt) == 0) {
     90                if (call->buffer)
     91                        free(call->buffer);
     92                slab_free(ipc_call_slab, call);
     93        }
     94}
     95
    8296/** Allocate and initialize a call structure.
    8397 *
     
    88102 *
    89103 * @return If flags permit it, return NULL, or initialized kernel
    90  *         call structure.
     104 *         call structure with one reference.
    91105 *
    92106 */
     
    94108{
    95109        call_t *call = slab_alloc(ipc_call_slab, flags);
    96         if (call)
     110        if (call) {
    97111                _ipc_call_init(call);
     112                ipc_call_hold(call);
     113        }
    98114       
    99115        return call;
     
    107123void ipc_call_free(call_t *call)
    108124{
    109         /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
    110         if (call->buffer)
    111                 free(call->buffer);
    112         slab_free(ipc_call_slab, call);
     125        ipc_call_release(call);
    113126}
    114127
     
    605618        list_remove(&call->ta_link);
    606619
     620        /*
     621         * The call may be freed by _ipc_answer_free_call() before we are done
     622         * with it; to avoid working with a destroyed call_t structure, we
     623         * must hold a reference to it.
     624         */
     625        ipc_call_hold(call);
     626
    607627        spinlock_unlock(&call->forget_lock);
    608628        spinlock_unlock(&TASK->active_calls_lock);
     
    613633        if (ops->request_forget)
    614634                ops->request_forget(call);
     635
     636        ipc_call_release(call);
    615637
    616638        goto restart;
Note: See TracChangeset for help on using the changeset viewer.