Changeset fe19611 in mainline


Ignore:
Timestamp:
2006-06-04T17:15:27Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c4e4507
Parents:
8adafa0
Message:

thread_join_timeout() and thread_detach() implementation.
Needs more thorough testing.

Location:
generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • generic/include/proc/thread.h

    r8adafa0 rfe19611  
    5252        Ready,          /**< State of threads in a run queue. */
    5353        Entering,       /**< Threads are in this state before they are first readied. */
    54         Exiting         /**< After a thread calls thread_exit(), it is put into Exiting state. */
     54        Exiting,        /**< After a thread calls thread_exit(), it is put into Exiting state. */
     55        Undead          /**< Threads that were not detached but exited are in the Undead state. */
    5556};
    5657
     
    9899        bool in_copy_to_uspace;
    99100
     101        bool detached;                          /**< If true, thread_join_timeout() cannot be used on this thread. */
     102        waitq_t join_wq;                        /**< Waitq for thread_join_timeout(). */
    100103
    101104        fpu_context_t *saved_fpu_context;
     
    152155extern void thread_usleep(__u32 usec);
    153156
     157extern int thread_join_timeout(thread_t *t, __u32 usec, int flags);
     158extern void thread_detach(thread_t *t);
     159
    154160extern void thread_register_call_me(void (* call_me)(void *), void *call_me_with);
    155161extern void thread_print_list(void);
  • generic/src/proc/scheduler.c

    r8adafa0 rfe19611  
    4141#include <mm/page.h>
    4242#include <mm/as.h>
     43#include <time/delay.h>
    4344#include <arch/asm.h>
    4445#include <arch/faddr.h>
     
    375376
    376377                    case Exiting:
    377                         thread_destroy(THREAD);
     378repeat:
     379                        if (THREAD->detached) {
     380                                thread_destroy(THREAD);
     381                        } else {
     382                                /*
     383                                 * The thread structure is kept allocated until somebody
     384                                 * calls thread_detach() on it.
     385                                 */
     386                                if (!spinlock_trylock(&THREAD->join_wq.lock)) {
     387                                        /*
     388                                         * Avoid deadlock.
     389                                         */
     390                                        spinlock_unlock(&THREAD->lock);
     391                                        delay(10);
     392                                        spinlock_lock(&THREAD->lock);
     393                                        goto repeat;
     394                                }
     395                                _waitq_wakeup_unsafe(&THREAD->join_wq, false);
     396                                spinlock_unlock(&THREAD->join_wq.lock);
     397                               
     398                                THREAD->state = Undead;
     399                                spinlock_unlock(&THREAD->lock);
     400                        }
    378401                        break;
    379402                       
  • generic/src/proc/thread.c

    r8adafa0 rfe19611  
    6464#include <errno.h>
    6565
    66 char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */
     66
     67/** Thread states */
     68char *thread_states[] = {
     69        "Invalid",
     70        "Running",
     71        "Sleeping",
     72        "Ready",
     73        "Entering",
     74        "Exiting",
     75        "Undead"
     76};
    6777
    6878/** Lock protecting threads_head list. For locking rules, see declaration thereof. */
     
    311321        t->in_copy_to_uspace = false;
    312322       
     323        t->detached = false;
     324        waitq_initialize(&t->join_wq);
     325       
    313326        t->rwlock_holder_type = RWLOCK_NONE;
    314327               
     
    372385{
    373386        thread_usleep(sec*1000000);
     387}
     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 */
     397int 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 */
     432void 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);
    374453}
    375454
Note: See TracChangeset for help on using the changeset viewer.