Rev 1502 | Rev 1579 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1502 | Rev 1571 | ||
|---|---|---|---|
| Line 61... | Line 61... | ||
| 61 | #include <debug.h> |
61 | #include <debug.h> |
| 62 | #include <main/uinit.h> |
62 | #include <main/uinit.h> |
| 63 | #include <syscall/copy.h> |
63 | #include <syscall/copy.h> |
| 64 | #include <errno.h> |
64 | #include <errno.h> |
| 65 | 65 | ||
| - | 66 | ||
| - | 67 | /** Thread states */ |
|
| 66 | char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */ |
68 | char *thread_states[] = { |
| - | 69 | "Invalid", |
|
| - | 70 | "Running", |
|
| - | 71 | "Sleeping", |
|
| - | 72 | "Ready", |
|
| - | 73 | "Entering", |
|
| - | 74 | "Exiting", |
|
| - | 75 | "Undead" |
|
| - | 76 | }; |
|
| 67 | 77 | ||
| 68 | /** Lock protecting threads_head list. For locking rules, see declaration thereof. */ |
78 | /** Lock protecting threads_head list. For locking rules, see declaration thereof. */ |
| 69 | SPINLOCK_INITIALIZE(threads_lock); |
79 | SPINLOCK_INITIALIZE(threads_lock); |
| 70 | btree_t threads_btree; /**< B+tree of all threads. */ |
80 | btree_t threads_btree; /**< B+tree of all threads. */ |
| 71 | 81 | ||
| Line 308... | Line 318... | ||
| 308 | t->timeout_pending = 0; |
318 | t->timeout_pending = 0; |
| 309 | 319 | ||
| 310 | t->in_copy_from_uspace = false; |
320 | t->in_copy_from_uspace = false; |
| 311 | t->in_copy_to_uspace = false; |
321 | t->in_copy_to_uspace = false; |
| 312 | 322 | ||
| - | 323 | t->detached = false; |
|
| - | 324 | waitq_initialize(&t->join_wq); |
|
| - | 325 | ||
| 313 | t->rwlock_holder_type = RWLOCK_NONE; |
326 | t->rwlock_holder_type = RWLOCK_NONE; |
| 314 | 327 | ||
| 315 | t->task = task; |
328 | t->task = task; |
| 316 | 329 | ||
| 317 | t->fpu_context_exists = 0; |
330 | t->fpu_context_exists = 0; |
| Line 371... | Line 384... | ||
| 371 | void thread_sleep(__u32 sec) |
384 | void thread_sleep(__u32 sec) |
| 372 | { |
385 | { |
| 373 | thread_usleep(sec*1000000); |
386 | thread_usleep(sec*1000000); |
| 374 | } |
387 | } |
| 375 | 388 | ||
| - | 389 | /** Wait for another thread to exit. |
|
| - | 390 | * |
|
| - | 391 | * @param t Thread to join on exit. |
|
| - | 392 | * @param usec Timeout in microseconds. |
|
| - | 393 | * @param flags Mode of operation. |
|
| - | 394 | * |
|
| - | 395 | * @return An error code from errno.h or an error code from synch.h. |
|
| - | 396 | */ |
|
| - | 397 | int thread_join_timeout(thread_t *t, __u32 usec, int flags) |
|
| - | 398 | { |
|
| - | 399 | ipl_t ipl; |
|
| - | 400 | int rc; |
|
| - | 401 | ||
| - | 402 | if (t == THREAD) |
|
| - | 403 | return EINVAL; |
|
| - | 404 | ||
| - | 405 | /* |
|
| - | 406 | * Since thread join can only be called once on an undetached thread, |
|
| - | 407 | * the thread pointer is guaranteed to be still valid. |
|
| - | 408 | */ |
|
| - | 409 | ||
| - | 410 | ipl = interrupts_disable(); |
|
| - | 411 | spinlock_lock(&t->lock); |
|
| - | 412 | ||
| - | 413 | ASSERT(!t->detached); |
|
| - | 414 | ||
| - | 415 | (void) waitq_sleep_prepare(&t->join_wq); |
|
| - | 416 | spinlock_unlock(&t->lock); |
|
| - | 417 | ||
| - | 418 | rc = waitq_sleep_timeout_unsafe(&t->join_wq, usec, flags); |
|
| - | 419 | ||
| - | 420 | waitq_sleep_finish(&t->join_wq, rc, ipl); |
|
| - | 421 | ||
| - | 422 | return rc; |
|
| - | 423 | } |
|
| - | 424 | ||
| - | 425 | /** Detach thread. |
|
| - | 426 | * |
|
| - | 427 | * Mark the thread as detached, if the thread is already in the Undead state, |
|
| - | 428 | * deallocate its resources. |
|
| - | 429 | * |
|
| - | 430 | * @param t Thread to be detached. |
|
| - | 431 | */ |
|
| - | 432 | void thread_detach(thread_t *t) |
|
| - | 433 | { |
|
| - | 434 | ipl_t ipl; |
|
| - | 435 | ||
| - | 436 | /* |
|
| - | 437 | * Since the thread is expected to not be already detached, |
|
| - | 438 | * pointer to it must be still valid. |
|
| - | 439 | */ |
|
| - | 440 | ||
| - | 441 | ipl = interrupts_disable(); |
|
| - | 442 | spinlock_lock(&t->lock); |
|
| - | 443 | ASSERT(!t->detached); |
|
| - | 444 | if (t->state == Undead) { |
|
| - | 445 | thread_destroy(t); /* unlocks &t->lock */ |
|
| - | 446 | interrupts_restore(ipl); |
|
| - | 447 | return; |
|
| - | 448 | } else { |
|
| - | 449 | t->detached = true; |
|
| - | 450 | } |
|
| - | 451 | spinlock_unlock(&t->lock); |
|
| - | 452 | interrupts_restore(ipl); |
|
| - | 453 | } |
|
| - | 454 | ||
| 376 | /** Thread usleep |
455 | /** Thread usleep |
| 377 | * |
456 | * |
| 378 | * Suspend execution of the current thread. |
457 | * Suspend execution of the current thread. |
| 379 | * |
458 | * |
| 380 | * @param usec Number of microseconds to sleep. |
459 | * @param usec Number of microseconds to sleep. |