Changeset 4b74488 in mainline


Ignore:
Timestamp:
2006-06-09T23:55:56Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6eb96fce
Parents:
7b3e7f4
Message:

Avoid tricky race condition between waitq_wakeup() and the pair
of waitq_timeouted_sleep() and waitq_interrupt_sleep().
Mutual exclusion != Synchronization.

File:
1 edited

Legend:

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

    r7b3e7f4 r4b74488  
    100100                t->saved_context = t->sleep_timeout_context;
    101101                do_wakeup = true;
    102                
     102                t->sleep_queue = NULL;
    103103                spinlock_unlock(&wq->lock);
    104                 t->sleep_queue = NULL;
    105104        }
    106105       
     
    155154                t->saved_context = t->sleep_interruption_context;
    156155                do_wakeup = true;
    157                
     156                t->sleep_queue = NULL;
    158157                spinlock_unlock(&wq->lock);
    159                 t->sleep_queue = NULL;
    160158        }
    161159        spinlock_unlock(&t->lock);
     
    419417        t = list_get_instance(wq->head.next, thread_t, wq_link);
    420418       
     419        /*
     420         * Lock the thread prior to removing it from the wq.
     421         * This is not necessary because of mutual exclusion
     422         * (the link belongs to the wait queue), but because
     423         * of synchronization with waitq_timeouted_sleep()
     424         * and waitq_interrupt_sleep().
     425         *
     426         * In order for these two functions to work, the following
     427         * invariant must hold:
     428         *
     429         * t->sleep_queue != NULL <=> t sleeps in a wait queue
     430         *
     431         * For an observer who locks the thread, the invariant
     432         * holds only when the lock is held prior to removing
     433         * it from the wait queue.
     434         */
     435        spinlock_lock(&t->lock);
    421436        list_remove(&t->wq_link);
    422         spinlock_lock(&t->lock);
     437       
    423438        if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
    424439                t->timeout_pending = false;
Note: See TracChangeset for help on using the changeset viewer.