Subversion Repositories HelenOS-historic

Rev

Rev 1 | Rev 25 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1 Rev 15
Line 127... Line 127...
127
     * This is an important fix for the race condition between
127
     * This is an important fix for the race condition between
128
     * a delayed timeout and a next call to waitq_sleep_timeout().
128
     * a delayed timeout and a next call to waitq_sleep_timeout().
129
     * Simply, the thread is not allowed to go to sleep if
129
     * Simply, the thread is not allowed to go to sleep if
130
     * there are timeouts in progress.
130
     * there are timeouts in progress.
131
     */
131
     */
132
    spinlock_lock(&the->thread->lock);
132
    spinlock_lock(&THREAD->lock);
133
    if (the->thread->timeout_pending) {
133
    if (THREAD->timeout_pending) {
134
        spinlock_unlock(&the->thread->lock);
134
        spinlock_unlock(&THREAD->lock);
135
        cpu_priority_restore(pri);     
135
        cpu_priority_restore(pri);     
136
        goto restart;
136
        goto restart;
137
    }
137
    }
138
    spinlock_unlock(&the->thread->lock);
138
    spinlock_unlock(&THREAD->lock);
139
   
139
   
140
    spinlock_lock(&wq->lock);
140
    spinlock_lock(&wq->lock);
141
   
141
   
142
    /* checks whether to go to sleep at all */
142
    /* checks whether to go to sleep at all */
143
    if (wq->missed_wakeups) {
143
    if (wq->missed_wakeups) {
Line 157... Line 157...
157
 
157
 
158
   
158
   
159
    /*
159
    /*
160
     * Now we are firmly decided to go to sleep.
160
     * Now we are firmly decided to go to sleep.
161
     */
161
     */
162
    spinlock_lock(&the->thread->lock);
162
    spinlock_lock(&THREAD->lock);
163
    if (usec) {
163
    if (usec) {
164
        /* We use the timeout variant. */
164
        /* We use the timeout variant. */
165
        if (!context_save(&the->thread->sleep_timeout_context)) {
165
        if (!context_save(&THREAD->sleep_timeout_context)) {
166
            /*
166
            /*
167
             * Short emulation of scheduler() return code.
167
             * Short emulation of scheduler() return code.
168
             */
168
             */
169
            spinlock_unlock(&the->thread->lock);
169
            spinlock_unlock(&THREAD->lock);
170
            cpu_priority_restore(pri);
170
            cpu_priority_restore(pri);
171
            return ESYNCH_TIMEOUT;
171
            return ESYNCH_TIMEOUT;
172
        }
172
        }
173
        the->thread->timeout_pending = 1;
173
        THREAD->timeout_pending = 1;
174
        timeout_register(&the->thread->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, the->thread);
174
        timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD);
175
    }
175
    }
176
 
176
 
177
    list_append(&the->thread->wq_link, &wq->head);
177
    list_append(&THREAD->wq_link, &wq->head);
178
 
178
 
179
    /*
179
    /*
180
     * Suspend execution.
180
     * Suspend execution.
181
     */
181
     */
182
    the->thread->state = Sleeping;
182
    THREAD->state = Sleeping;
183
    the->thread->sleep_queue = wq;
183
    THREAD->sleep_queue = wq;
184
 
184
 
185
    spinlock_unlock(&the->thread->lock);
185
    spinlock_unlock(&THREAD->lock);
186
 
186
 
187
    scheduler();    /* wq->lock is released in scheduler_separated_stack() */
187
    scheduler();    /* wq->lock is released in scheduler_separated_stack() */
188
    cpu_priority_restore(pri);
188
    cpu_priority_restore(pri);
189
   
189
   
190
    return ESYNCH_OK_BLOCKED;
190
    return ESYNCH_OK_BLOCKED;