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. |