Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1570 → Rev 1571

/kernel/trunk/generic/src/proc/scheduler.c
40,6 → 40,7
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/as.h>
#include <time/delay.h>
#include <arch/asm.h>
#include <arch/faddr.h>
#include <atomic.h>
374,7 → 375,29
break;
 
case Exiting:
thread_destroy(THREAD);
repeat:
if (THREAD->detached) {
thread_destroy(THREAD);
} else {
/*
* The thread structure is kept allocated until somebody
* calls thread_detach() on it.
*/
if (!spinlock_trylock(&THREAD->join_wq.lock)) {
/*
* Avoid deadlock.
*/
spinlock_unlock(&THREAD->lock);
delay(10);
spinlock_lock(&THREAD->lock);
goto repeat;
}
_waitq_wakeup_unsafe(&THREAD->join_wq, false);
spinlock_unlock(&THREAD->join_wq.lock);
THREAD->state = Undead;
spinlock_unlock(&THREAD->lock);
}
break;
case Sleeping:
/kernel/trunk/generic/src/proc/thread.c
63,8 → 63,18
#include <syscall/copy.h>
#include <errno.h>
 
char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */
 
/** Thread states */
char *thread_states[] = {
"Invalid",
"Running",
"Sleeping",
"Ready",
"Entering",
"Exiting",
"Undead"
};
 
/** Lock protecting threads_head list. For locking rules, see declaration thereof. */
SPINLOCK_INITIALIZE(threads_lock);
btree_t threads_btree; /**< B+tree of all threads. */
310,6 → 320,9
t->in_copy_from_uspace = false;
t->in_copy_to_uspace = false;
t->detached = false;
waitq_initialize(&t->join_wq);
t->rwlock_holder_type = RWLOCK_NONE;
t->task = task;
373,6 → 386,72
thread_usleep(sec*1000000);
}
 
/** Wait for another thread to exit.
*
* @param t Thread to join on exit.
* @param usec Timeout in microseconds.
* @param flags Mode of operation.
*
* @return An error code from errno.h or an error code from synch.h.
*/
int thread_join_timeout(thread_t *t, __u32 usec, int flags)
{
ipl_t ipl;
int rc;
 
if (t == THREAD)
return EINVAL;
 
/*
* Since thread join can only be called once on an undetached thread,
* the thread pointer is guaranteed to be still valid.
*/
ipl = interrupts_disable();
spinlock_lock(&t->lock);
 
ASSERT(!t->detached);
(void) waitq_sleep_prepare(&t->join_wq);
spinlock_unlock(&t->lock);
rc = waitq_sleep_timeout_unsafe(&t->join_wq, usec, flags);
waitq_sleep_finish(&t->join_wq, rc, ipl);
return rc;
}
 
/** Detach thread.
*
* Mark the thread as detached, if the thread is already in the Undead state,
* deallocate its resources.
*
* @param t Thread to be detached.
*/
void thread_detach(thread_t *t)
{
ipl_t ipl;
 
/*
* Since the thread is expected to not be already detached,
* pointer to it must be still valid.
*/
ipl = interrupts_disable();
spinlock_lock(&t->lock);
ASSERT(!t->detached);
if (t->state == Undead) {
thread_destroy(t); /* unlocks &t->lock */
interrupts_restore(ipl);
return;
} else {
t->detached = true;
}
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
}
 
/** Thread usleep
*
* Suspend execution of the current thread.