Changeset 83789ea2 in mainline
- Timestamp:
- 2023-02-09T16:12:24Z (21 months ago)
- Branches:
- master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c0b54c9
- Parents:
- ba25c4b
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2022-08-16 17:52:15)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-09 16:12:24)
- Location:
- kernel/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/proc/thread.h
rba25c4b r83789ea2 121 121 /** Wait queue in which this thread sleeps. */ 122 122 waitq_t *sleep_queue; 123 /** Timeout used for timeoutable sleeping. */124 timeout_t sleep_timeout;125 /** Flag signalling sleep timeout in progress. */126 volatile bool timeout_pending;127 123 128 124 /** -
kernel/generic/src/proc/thread.c
rba25c4b r83789ea2 360 360 thread->state = Entering; 361 361 362 timeout_initialize(&thread->sleep_timeout);363 362 thread->sleep_interruptible = false; 364 363 thread->sleep_composable = false; 365 364 thread->sleep_queue = NULL; 366 thread->timeout_pending = false;367 365 368 366 thread->in_copy_from_uspace = false; … … 500 498 } 501 499 502 restart:503 500 irq_spinlock_lock(&THREAD->lock, true); 504 if (THREAD->timeout_pending) {505 /* Busy waiting for timeouts in progress */506 irq_spinlock_unlock(&THREAD->lock, true);507 goto restart;508 }509 510 501 THREAD->state = Exiting; 511 502 irq_spinlock_unlock(&THREAD->lock, true); -
kernel/generic/src/synch/waitq.c
rba25c4b r83789ea2 121 121 } 122 122 123 thread->timeout_pending = false;124 123 irq_spinlock_unlock(&thread->lock, false); 125 124 … … 172 171 goto grab_locks; 173 172 } 174 175 if ((thread->timeout_pending) &&176 (timeout_unregister(&thread->sleep_timeout)))177 thread->timeout_pending = false;178 173 179 174 list_remove(&thread->wq_link); … … 270 265 ipl_t waitq_sleep_prepare(waitq_t *wq) 271 266 { 272 ipl_t ipl; 273 274 restart: 275 ipl = interrupts_disable(); 276 277 if (THREAD) { /* Needed during system initiailzation */ 278 /* 279 * Busy waiting for a delayed timeout. 280 * This is an important fix for the race condition between 281 * a delayed timeout and a next call to waitq_sleep_timeout(). 282 * Simply, the thread is not allowed to go to sleep if 283 * there are timeouts in progress. 284 * 285 */ 286 irq_spinlock_lock(&THREAD->lock, false); 287 288 if (THREAD->timeout_pending) { 289 irq_spinlock_unlock(&THREAD->lock, false); 290 interrupts_restore(ipl); 291 goto restart; 292 } 293 294 irq_spinlock_unlock(&THREAD->lock, false); 295 } 296 267 ipl_t ipl = interrupts_disable(); 297 268 irq_spinlock_lock(&wq->lock, false); 298 269 return ipl; … … 374 345 irq_spinlock_lock(&THREAD->lock, false); 375 346 347 timeout_t timeout; 348 timeout_initialize(&timeout); 349 376 350 THREAD->sleep_composable = (flags & SYNCH_FLAGS_FUTEX); 377 351 … … 395 369 THREAD->last_cycle = get_cycle(); 396 370 irq_spinlock_unlock(&THREAD->lock, false); 371 if (usec) { 372 timeout_unregister(&timeout); 373 } 397 374 return EINTR; 398 375 } … … 409 386 } 410 387 411 THREAD->timeout_pending = true; 412 timeout_register(&THREAD->sleep_timeout, (uint64_t) usec, 413 waitq_sleep_timed_out, THREAD); 388 timeout_register(&timeout, (uint64_t) usec, waitq_sleep_timed_out, THREAD); 414 389 } 415 390 … … 433 408 /* wq->lock is released in scheduler_separated_stack() */ 434 409 scheduler(); 410 411 if (usec) { 412 timeout_unregister(&timeout); 413 } 435 414 436 415 return EOK; … … 560 539 list_remove(&thread->wq_link); 561 540 562 if ((thread->timeout_pending) &&563 (timeout_unregister(&thread->sleep_timeout)))564 thread->timeout_pending = false;565 566 541 thread->sleep_queue = NULL; 567 542 irq_spinlock_unlock(&thread->lock, false); -
kernel/generic/src/time/timeout.c
rba25c4b r83789ea2 128 128 bool timeout_unregister(timeout_t *timeout) 129 129 { 130 if (atomic_load_explicit(&timeout->finished, memory_order_acquire)) 131 /* The timeout fired and finished already, no need to check the list. */ 132 return false; 133 130 134 assert(timeout->cpu); 131 135
Note:
See TracChangeset
for help on using the changeset viewer.