Changeset 9306cd7 in mainline for kernel/generic/src/ipc/irq.c
- Timestamp:
- 2017-09-03T18:14:15Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3422fb6
- Parents:
- 4d6629f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ipc/irq.c
r4d6629f r9306cd7 329 329 cap_t *cap = cap_get_current(handle, CAP_TYPE_ALLOCATED); 330 330 assert(cap); 331 cap->type = CAP_TYPE_IRQ; 332 331 333 332 irq_t *irq = &cap->irq; 334 333 irq_initialize(irq); … … 344 343 /* 345 344 * Enlist the IRQ structure in the uspace IRQ hash table and the 346 * answerbox's list .345 * answerbox's list and make the IRQ capability valid. 347 346 */ 348 347 irq_spinlock_lock(&irq_uspace_hash_table_lock, true); … … 350 349 irq_spinlock_lock(&box->irq_lock, false); 351 350 351 cap->type = CAP_TYPE_IRQ; 352 352 hash_table_insert(&irq_uspace_hash_table, key, &irq->link); 353 353 list_append(&irq->notif_cfg.link, &box->irq_list); … … 370 370 int ipc_irq_unsubscribe(answerbox_t *box, int handle) 371 371 { 372 irq_spinlock_lock(&TASK->lock, true); 372 373 cap_t *cap = cap_get_current(handle, CAP_TYPE_IRQ); 373 if (!cap) 374 if (!cap) { 375 irq_spinlock_unlock(&TASK->lock, true); 374 376 return ENOENT; 377 } 378 cap->type = CAP_TYPE_ALLOCATED; 379 irq_spinlock_unlock(&TASK->lock, true); 380 375 381 irq_t *irq = &cap->irq; 376 382 377 383 irq_spinlock_lock(&irq_uspace_hash_table_lock, true); 378 384 irq_spinlock_lock(&irq->lock, false); … … 398 404 399 405 return EOK; 400 }401 402 /** Disconnect all IRQ notifications from an answerbox.403 *404 * This function is effective because the answerbox contains list of all irq_t405 * structures that are subscribed to send notifications to it.406 *407 * @param box Answerbox for which we want to carry out the cleanup.408 *409 */410 void ipc_irq_cleanup(answerbox_t *box)411 {412 loop:413 irq_spinlock_lock(&irq_uspace_hash_table_lock, true);414 irq_spinlock_lock(&box->irq_lock, false);415 416 while (!list_empty(&box->irq_list)) {417 DEADLOCK_PROBE_INIT(p_irqlock);418 419 irq_t *irq = list_get_instance(list_first(&box->irq_list), irq_t,420 notif_cfg.link);421 422 if (!irq_spinlock_trylock(&irq->lock)) {423 /*424 * Avoid deadlock by trying again.425 */426 irq_spinlock_unlock(&box->irq_lock, false);427 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);428 DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);429 goto loop;430 }431 432 assert(irq->notif_cfg.answerbox == box);433 434 /* Unlist from the answerbox. */435 list_remove(&irq->notif_cfg.link);436 437 /* Remove from the hash table. */438 hash_table_remove_item(&irq_uspace_hash_table, &irq->link);439 440 /*441 * Release both locks so that we can free the IRQ code.442 */443 irq_spinlock_unlock(&box->irq_lock, false);444 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);445 446 code_free(irq->notif_cfg.code);447 448 // XXX: what to do about the irq capability? The task is in449 // clean-up anyway.450 451 /* Reacquire both locks before taking another round. */452 irq_spinlock_lock(&irq_uspace_hash_table_lock, true);453 irq_spinlock_lock(&box->irq_lock, false);454 }455 456 irq_spinlock_unlock(&box->irq_lock, false);457 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);458 406 } 459 407
Note:
See TracChangeset
for help on using the changeset viewer.