Ignore:
File:
1 edited

Legend:

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

    r9fc776c7 r5a6cc679  
    235235}
    236236
     237static bool cap_reclaimer(ht_link_t *link, void *arg)
     238{
     239        cap_t **result = (cap_t **) arg;
     240        cap_t *cap = hash_table_get_inst(link, cap_t, caps_link);
     241
     242        if (cap->state == CAP_STATE_PUBLISHED && cap->kobject->ops->reclaim &&
     243            cap->kobject->ops->reclaim(cap->kobject)) {
     244                kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
     245                    cap->kobject->type);
     246                kobject_put(kobj);
     247                cap_initialize(cap, cap->task, cap->handle);
     248                *result = cap;
     249                return false;
     250        }
     251
     252        return true;
     253}
     254
    237255/** Allocate new capability
    238256 *
     
    245263errno_t cap_alloc(task_t *task, cap_handle_t *handle)
    246264{
    247         mutex_lock(&task->cap_info->lock);
    248         cap_t *cap = slab_alloc(cap_cache, FRAME_ATOMIC);
     265        cap_t *cap = NULL;
     266
     267        /*
     268         * First of all, see if we can reclaim a capability. Note that this
     269         * feature is only temporary and capability reclamaition will eventually
     270         * be phased out.
     271         */
     272        mutex_lock(&task->cap_info->lock);
     273        hash_table_apply(&task->cap_info->caps, cap_reclaimer, &cap);
     274
     275        /*
     276         * If we don't have a capability by now, try to allocate a new one.
     277         */
    249278        if (!cap) {
    250                 mutex_unlock(&task->cap_info->lock);
    251                 return ENOMEM;
    252         }
    253         uintptr_t hbase;
    254         if (!ra_alloc(task->cap_info->handles, 1, 1, &hbase)) {
    255                 slab_free(cap_cache, cap);
    256                 mutex_unlock(&task->cap_info->lock);
    257                 return ENOMEM;
    258         }
    259         cap_initialize(cap, task, (cap_handle_t) hbase);
    260         hash_table_insert(&task->cap_info->caps, &cap->caps_link);
     279                cap = slab_alloc(cap_cache, FRAME_ATOMIC);
     280                if (!cap) {
     281                        mutex_unlock(&task->cap_info->lock);
     282                        return ENOMEM;
     283                }
     284                uintptr_t hbase;
     285                if (!ra_alloc(task->cap_info->handles, 1, 1, &hbase)) {
     286                        slab_free(cap_cache, cap);
     287                        mutex_unlock(&task->cap_info->lock);
     288                        return ENOMEM;
     289                }
     290                cap_initialize(cap, task, (cap_handle_t) hbase);
     291                hash_table_insert(&task->cap_info->caps, &cap->caps_link);
     292        }
    261293
    262294        cap->state = CAP_STATE_ALLOCATED;
Note: See TracChangeset for help on using the changeset viewer.