Changes in kernel/generic/src/cap/cap.c [455241b:b596d0d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/cap/cap.c
r455241b rb596d0d 93 93 94 94 #define CAPS_START ((intptr_t) CAP_NIL + 1) 95 #define CAPS_ LAST ((intptr_t) INT_MAX - 1)96 #define CAPS_ SIZE (CAPS_LAST - CAPS_START +1)95 #define CAPS_SIZE (INT_MAX - (int) CAPS_START) 96 #define CAPS_LAST (CAPS_SIZE - 1) 97 97 98 98 static slab_cache_t *cap_cache; 99 static slab_cache_t *kobject_cache; 99 100 100 101 kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = { … … 124 125 } 125 126 126 static void caps_remove_callback(ht_link_t *item)127 {128 cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);129 130 if (cap->kobject) {131 kobject_t *kobj = cap->kobject;132 133 mutex_lock(&kobj->caps_list_lock);134 cap->kobject = NULL;135 list_remove(&cap->kobj_link);136 mutex_unlock(&kobj->caps_list_lock);137 138 kobject_put(kobj);139 }140 141 list_remove(&cap->type_link);142 143 slab_free(cap_cache, cap);144 }145 146 127 static const hash_table_ops_t caps_ops = { 147 128 .hash = caps_hash, 148 129 .key_hash = caps_key_hash, 149 .key_equal = caps_key_equal, 150 .remove_callback = caps_remove_callback, 130 .key_equal = caps_key_equal 151 131 }; 152 132 … … 155 135 cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL, 156 136 NULL, 0); 137 kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0, 138 NULL, NULL, 0); 157 139 } 158 140 … … 166 148 if (!task->cap_info) 167 149 return ENOMEM; 168 169 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) { 170 free(task->cap_info); 171 return ENOMEM; 172 } 173 150 task->cap_info->handles = ra_arena_create(); 151 if (!task->cap_info->handles) 152 goto error_handles; 153 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) 154 goto error_span; 155 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) 156 goto error_span; 157 return EOK; 158 159 error_span: 160 ra_arena_destroy(task->cap_info->handles); 161 error_handles: 162 free(task->cap_info); 163 return ENOMEM; 164 } 165 166 /** Initialize the capability info structure 167 * 168 * @param task Task for which to initialize the info structure. 169 */ 170 void caps_task_init(task_t *task) 171 { 174 172 mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE); 175 176 task->cap_info->handles = NULL;177 173 178 174 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 179 175 list_initialize(&task->cap_info->type_list[t]); 180 181 return EOK;182 }183 184 /** Initialize the capability info structure185 *186 * @param task Task for which to initialize the info structure.187 */188 errno_t caps_task_init(task_t *task)189 {190 assert(task->cap_info);191 assert(!task->cap_info->handles);192 193 task->cap_info->handles = ra_arena_create();194 if (!task->cap_info->handles)195 return ENOMEM;196 197 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) {198 ra_arena_destroy(task->cap_info->handles);199 return ENOMEM;200 }201 202 return EOK;203 }204 205 void caps_task_clear(task_t *task)206 {207 mutex_lock(&task->cap_info->lock);208 209 hash_table_clear(&task->cap_info->caps);210 211 if (task->cap_info->handles) {212 ra_arena_destroy(task->cap_info->handles);213 task->cap_info->handles = NULL;214 }215 216 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)217 list_initialize(&task->cap_info->type_list[t]);218 219 mutex_unlock(&task->cap_info->lock);220 176 } 221 177 … … 227 183 { 228 184 hash_table_destroy(&task->cap_info->caps); 229 230 if (task->cap_info->handles) 231 ra_arena_destroy(task->cap_info->handles); 232 185 ra_arena_destroy(task->cap_info->handles); 233 186 free(task->cap_info); 234 187 } … … 347 300 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) 348 301 { 349 mutex_lock(&task->cap_info->lock);350 302 mutex_lock(&kobj->caps_list_lock); 303 mutex_lock(&task->cap_info->lock); 351 304 cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED); 352 305 assert(cap); … … 356 309 list_append(&cap->kobj_link, &kobj->caps_list); 357 310 list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]); 311 mutex_unlock(&task->cap_info->lock); 358 312 mutex_unlock(&kobj->caps_list_lock); 359 mutex_unlock(&task->cap_info->lock);360 313 } 361 314 … … 387 340 kobject_t *kobj = NULL; 388 341 342 restart: 389 343 mutex_lock(&task->cap_info->lock); 390 344 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); … … 393 347 /* Hand over cap's reference to kobj */ 394 348 kobj = cap->kobject; 395 396 mutex_lock(&kobj->caps_list_lock); 349 if (mutex_trylock(&kobj->caps_list_lock) != EOK) { 350 mutex_unlock(&task->cap_info->lock); 351 kobj = NULL; 352 goto restart; 353 } 397 354 cap_unpublish_unsafe(cap); 398 355 mutex_unlock(&kobj->caps_list_lock); … … 419 376 { 420 377 mutex_lock(&kobj->caps_list_lock); 421 422 while (!list_empty(&kobj->caps_list)) { 423 cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link); 424 425 /* We're trying to acquire the two locks in reverse order. */ 426 if (mutex_trylock(&cap->task->cap_info->lock) != EOK) { 427 mutex_unlock(&kobj->caps_list_lock); 428 mutex_lock(&kobj->caps_list_lock); 429 continue; 430 } 431 378 list_foreach_safe(kobj->caps_list, cur, hlp) { 379 cap_t *cap = list_get_instance(cur, cap_t, kobj_link); 380 mutex_lock(&cap->task->cap_info->lock); 432 381 cap_unpublish_unsafe(cap); 433 382 /* Drop the reference for the unpublished capability */ 434 383 kobject_put(kobj); 435 436 384 mutex_unlock(&cap->task->cap_info->lock); 437 385 } 438 439 386 mutex_unlock(&kobj->caps_list_lock); 440 387 } … … 457 404 hash_table_remove_item(&task->cap_info->caps, &cap->caps_link); 458 405 ra_free(task->cap_info->handles, cap_handle_raw(handle), 1); 459 mutex_unlock(&task->cap_info->lock); 406 slab_free(cap_cache, cap); 407 mutex_unlock(&task->cap_info->lock); 408 } 409 410 kobject_t *kobject_alloc(unsigned int flags) 411 { 412 return slab_alloc(kobject_cache, flags); 413 } 414 415 void kobject_free(kobject_t *kobj) 416 { 417 slab_free(kobject_cache, kobj); 460 418 } 461 419 … … 464 422 * @param kobj Kernel object to initialize. 465 423 * @param type Type of the kernel object. 466 */ 467 void kobject_initialize(kobject_t *kobj, kobject_type_t type) 468 { 469 refcount_init(&kobj->refcnt); 424 * @param raw Raw pointer to the encapsulated object. 425 */ 426 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw) 427 { 428 atomic_store(&kobj->refcnt, 1); 470 429 471 430 mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE); … … 473 432 474 433 kobj->type = type; 434 kobj->raw = raw; 475 435 } 476 436 … … 495 455 if (cap->kobject->type == type) { 496 456 kobj = cap->kobject; 497 refcount_up(&kobj->refcnt);457 atomic_inc(&kobj->refcnt); 498 458 } 499 459 } … … 509 469 void kobject_add_ref(kobject_t *kobj) 510 470 { 511 refcount_up(&kobj->refcnt);471 atomic_inc(&kobj->refcnt); 512 472 } 513 473 … … 521 481 void kobject_put(kobject_t *kobj) 522 482 { 523 if (refcount_down(&kobj->refcnt)) { 524 KOBJECT_OP(kobj)->destroy(kobj); 483 if (atomic_postdec(&kobj->refcnt) == 1) { 484 KOBJECT_OP(kobj)->destroy(kobj->raw); 485 kobject_free(kobj); 525 486 } 526 487 }
Note:
See TracChangeset
for help on using the changeset viewer.