Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 786 → Rev 787

/kernel/trunk/generic/src/proc/thread.c
52,6 → 52,8
#include <arch/atomic.h>
#include <memstr.h>
#include <print.h>
#include <mm/slab.h>
#include <debug.h>
 
char *thread_states[] = {"Invalid", "Running", "Sleeping", "Ready", "Entering", "Exiting"}; /**< Thread states */
 
61,7 → 63,9
SPINLOCK_INITIALIZE(tidlock);
__u32 last_tid = 0;
 
static slab_cache_t *thread_slab;
 
 
/** Thread wrapper
*
* This wrapper is provided to ensure that every thread
87,7 → 91,33
/* not reached */
}
 
/** Initialization and allocation for thread_t structure */
static int thr_constructor(void *obj, int kmflags)
{
thread_t *t = (thread_t *)obj;
 
spinlock_initialize(&t->lock, "thread_t_lock");
link_initialize(&t->rq_link);
link_initialize(&t->wq_link);
link_initialize(&t->th_link);
link_initialize(&t->threads_link);
t->kstack = (__u8 *)frame_alloc(ONE_FRAME, FRAME_KA | kmflags);
if (!t->kstack)
return -1;
 
return 0;
}
 
/** Destruction of thread_t object */
static int thr_destructor(void *obj)
{
thread_t *t = (thread_t *)obj;
 
frame_free((__address) t->kstack);
return 1; /* One page freed */
}
 
/** Initialize threads
*
* Initialize kernel threads support.
97,6 → 127,9
{
THREAD = NULL;
atomic_set(&nrdy,0);
thread_slab = slab_cache_create("thread_slab",
sizeof(thread_t),0,
thr_constructor, thr_destructor, 0);
}
 
 
143,6 → 176,43
}
 
 
/** Destroy thread memory structure
*
* Detach thread from all queues, cpus etc. and destroy it.
*
* Assume thread->lock is held!!
*/
void thread_destroy(thread_t *t)
{
ASSERT(t->state == Exiting);
ASSERT(t->task);
ASSERT(t->cpu);
 
spinlock_lock(&t->cpu->lock);
if(t->cpu->fpu_owner==t)
t->cpu->fpu_owner=NULL;
spinlock_unlock(&t->cpu->lock);
 
if (t->ustack)
frame_free((__address) t->ustack);
/*
* Detach from the containing task.
*/
spinlock_lock(&t->task->lock);
list_remove(&t->th_link);
spinlock_unlock(&t->task->lock);
spinlock_unlock(&t->lock);
spinlock_lock(&threads_lock);
list_remove(&t->threads_link);
spinlock_unlock(&threads_lock);
slab_free(thread_slab, t);
}
 
 
/** Create new thread
*
* Create a new thread.
158,19 → 228,19
thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags)
{
thread_t *t;
__address frame_ks, frame_us = NULL;
__address frame_us = NULL;
 
t = (thread_t *) malloc(sizeof(thread_t));
t = (thread_t *) slab_alloc(thread_slab, 0);
if (t) {
ipl_t ipl;
spinlock_initialize(&t->lock, "thread_t_lock");
frame_ks = frame_alloc(ONE_FRAME, FRAME_KA);
if (THREAD_USER_STACK & flags) {
frame_us = frame_alloc(ONE_FRAME, FRAME_KA);
}
 
/* Not needed, but good for debugging */
memsetb((__address)t->kstack, THREAD_STACK_SIZE, 0);
 
ipl = interrupts_disable();
spinlock_lock(&tidlock);
t->tid = ++last_tid;
177,12 → 247,6
spinlock_unlock(&tidlock);
interrupts_restore(ipl);
memsetb(frame_ks, THREAD_STACK_SIZE, 0);
link_initialize(&t->rq_link);
link_initialize(&t->wq_link);
link_initialize(&t->th_link);
link_initialize(&t->threads_link);
t->kstack = (__u8 *) frame_ks;
t->ustack = (__u8 *) frame_us;
context_save(&t->saved_context);
218,7 → 282,7
/*
* Register this thread in the system-wide list.
*/
ipl = interrupts_disable();
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
list_append(&t->threads_link, &threads_head);
spinlock_unlock(&threads_lock);