Changeset 9fe9d296 in mainline for kernel/generic/src/synch/waitq.c


Ignore:
Timestamp:
2012-11-16T17:36:23Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
853d613
Parents:
497bd656
Message:

Fix: waitq_sleep_timeout() waits for its waitq_wakeup() to complete unconditionally. No need to wait explicitly via waitq_complete_wakeup() anymore.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified kernel/generic/src/synch/waitq.c

    r497bd656 r9fe9d296  
    5757
    5858static void waitq_sleep_timed_out(void *);
     59static void waitq_complete_wakeup(waitq_t *);
     60
    5961
    6062/** Initialize wait queue
     
    330332                break;
    331333        default:
     334                /*
     335                 * Wait for a waitq_wakeup() or waitq_unsleep() to complete
     336                 * before returning from waitq_sleep() to the caller. Otherwise
     337                 * the caller might expect that the wait queue is no longer used
     338                 * and deallocate it (although the wakeup on a another cpu has
     339                 * not yet completed and is using the wait queue).
     340                 *
     341                 * Note that we have to do this for ESYNCH_OK_BLOCKED and
     342                 * ESYNCH_INTERRUPTED, but not necessarily for ESYNCH_TIMEOUT
     343                 * where the timeout handler stops using the waitq before waking
     344                 * us up. To be on the safe side, ensure the waitq is not in use
     345                 * anymore in this case as well.
     346                 */
     347                waitq_complete_wakeup(wq);
    332348                break;
    333349        }
     
    357373        } else {
    358374                if (PARAM_NON_BLOCKING(flags, usec)) {
    359                         /* Return immediatelly instead of going to sleep */
     375                        /* Return immediately instead of going to sleep */
    360376                        return ESYNCH_WOULD_BLOCK;
    361377                }
     
    448464 * exits. It returns immediately if there are no concurrent wakeups
    449465 * at the time.
     466 *
     467 * Interrupts must be disabled.
    450468 *
    451469 * Example usage:
     
    466484 *     // callback() completed its work, but it may still be accessing
    467485 *     // wq in waitq_wakeup(). Therefore it is not yet safe to return
    468  *     // or it would clobber up our stack (where wq is stored).
    469  *     waitq_complete_wakeup(&wq);
    470  *     // waitq_wakeup() is complete, it is safe to free wq.
     486 *     // from waitq_sleep() or it would clobber up our stack (where wq
     487 *     // is stored). waitq_sleep() ensures the wait queue is no longer
     488 *     // in use by invoking waitq_complete_wakeup() internally.
     489 *     
     490 *     // waitq_sleep() returned, it is safe to free wq.
    471491 * }
    472492 * @endcode
     
    474494 * @param wq  Pointer to a wait queue.
    475495 */
    476 void waitq_complete_wakeup(waitq_t *wq)
    477 {
    478         irq_spinlock_lock(&wq->lock, true);
    479         irq_spinlock_unlock(&wq->lock, true);
     496static void waitq_complete_wakeup(waitq_t *wq)
     497{
     498        ASSERT(interrupts_disabled());
     499       
     500        irq_spinlock_lock(&wq->lock, false);
     501        irq_spinlock_unlock(&wq->lock, false);
    480502}
    481503
Note: See TracChangeset for help on using the changeset viewer.