Changeset 48bcf49 in mainline for kernel/generic/src/ipc/ipcrsc.c


Ignore:
Timestamp:
2017-09-28T22:08:15Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6636fb19
Parents:
dd20cbb
Message:

Introduce reference-counted kobjects

Capabilities are thus reduced to task-local names for references to kobjects.

File:
1 edited

Legend:

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

    rdd20cbb r48bcf49  
    164164}
    165165
    166 /** Get phone from the current task by capability handle.
    167  *
    168  * @param handle  Phone capability handle.
    169  * @param phone   Place to store pointer to phone.
    170  *
    171  * @return  Address of the phone kernel object.
    172  * @return  NULL if the capability is invalid.
    173  *
    174  */
    175 phone_t *phone_get(task_t *task, int handle)
    176 {
    177         phone_t *phone;
    178 
    179         caps_lock(task);
    180         cap_t *cap = cap_get(task, handle, CAP_TYPE_PHONE);
    181         phone = (phone_t *) cap->kobject;
    182         caps_unlock(task);
    183         if (!cap)
    184                 return NULL;
    185        
    186         return phone;
    187 }
    188 
    189 phone_t *phone_get_current(int handle)
    190 {
    191         return phone_get(TASK, handle);
    192 }
    193 
    194 static bool phone_can_reclaim(cap_t *cap)
    195 {
    196         assert(cap->type == CAP_TYPE_PHONE);
    197 
    198         phone_t *phone = (phone_t *) cap->kobject;
    199 
    200         return (phone->state == IPC_PHONE_HUNGUP) &&
    201             (atomic_get(&phone->active_calls) == 0);
    202 }
     166static bool phone_reclaim(kobject_t *kobj)
     167{
     168        bool gc = false;
     169
     170        mutex_lock(&kobj->phone->lock);
     171        if (kobj->phone->state == IPC_PHONE_HUNGUP &&
     172            atomic_get(&kobj->phone->active_calls) == 0)
     173                gc = true;
     174        mutex_unlock(&kobj->phone->lock);
     175
     176        return gc;
     177}
     178
     179static void phone_destroy(void *arg)
     180{
     181        phone_t *phone = (phone_t *) arg;
     182        slab_free(phone_slab, phone);
     183}
     184
     185static kobject_ops_t phone_kobject_ops = {
     186        .reclaim = phone_reclaim,
     187        .destroy = phone_destroy
     188};
     189
    203190
    204191/** Allocate new phone in the specified task.
     
    209196 * @return  Negative error code if a new capability cannot be allocated.
    210197 */
    211 int phone_alloc(task_t *task)
    212 {
    213         int handle = cap_alloc(task);
     198cap_handle_t phone_alloc(task_t *task)
     199{
     200        cap_handle_t handle = cap_alloc(task);
    214201        if (handle >= 0) {
    215202                phone_t *phone = slab_alloc(phone_slab, FRAME_ATOMIC);
     
    218205                        return ENOMEM;
    219206                }
    220                
     207                kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     208                if (!kobject) {
     209                        cap_free(TASK, handle);
     210                        slab_free(phone_slab, phone);
     211                        return ENOMEM;
     212                }
     213
    221214                ipc_phone_init(phone, task);
    222215                phone->state = IPC_PHONE_CONNECTING;
     216
     217                kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
     218                    &phone_kobject_ops);
     219                phone->kobject = kobject;
    223220               
    224                 // FIXME: phase this out eventually
    225                 mutex_lock(&task->cap_info->lock);
    226                 cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
    227                 cap->can_reclaim = phone_can_reclaim;
    228                 mutex_unlock(&task->cap_info->lock);
    229 
    230                 cap_publish(task, handle, CAP_TYPE_PHONE, phone);
     221                cap_publish(task, handle, kobject);
    231222        }
    232223       
     
    241232 *
    242233 */
    243 void phone_dealloc(int handle)
    244 {
    245         cap_t *cap = cap_unpublish(TASK, handle, CAP_TYPE_PHONE);
    246         assert(cap);
    247        
    248         phone_t *phone = (phone_t *) cap->kobject;
    249        
    250         assert(phone);
    251         assert(phone->state == IPC_PHONE_CONNECTING);
    252        
    253         slab_free(phone_slab, phone);
     234void phone_dealloc(cap_handle_t handle)
     235{
     236        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
     237        if (!kobj)
     238                return;
     239       
     240        assert(kobj->phone);
     241        assert(kobj->phone->state == IPC_PHONE_CONNECTING);
     242       
     243        kobject_put(kobj);
    254244        cap_free(TASK, handle);
    255245}
     
    260250 * @param box     Answerbox to which to connect the phone.
    261251 * @return        True if the phone was connected, false otherwise.
    262  *
    263  * The procedure _enforces_ that the user first marks the phone busy (e.g. via
    264  * phone_alloc) and then connects the phone, otherwise race condition may
    265  * appear.
    266  *
    267  */
    268 bool phone_connect(int handle, answerbox_t *box)
    269 {
    270         phone_t *phone = phone_get_current(handle);
    271        
    272         assert(phone);
    273         assert(phone->state == IPC_PHONE_CONNECTING);
    274        
    275         return ipc_phone_connect(phone, box);
     252 */
     253bool phone_connect(cap_handle_t handle, answerbox_t *box)
     254{
     255        kobject_t *phone_obj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     256        if (!phone_obj)
     257                return false;
     258       
     259        assert(phone_obj->phone->state == IPC_PHONE_CONNECTING);
     260       
     261        /* Hand over phone_obj reference to the answerbox */
     262        return ipc_phone_connect(phone_obj->phone, box);
    276263}
    277264
Note: See TracChangeset for help on using the changeset viewer.