/branches/rcu/kernel/generic/src/proc/scheduler.c |
---|
61,6 → 61,7 |
#include <cpu.h> |
#include <print.h> |
#include <debug.h> |
#include <synch/rcu.h> |
static void before_task_runs(void); |
static void before_thread_runs(void); |
115,6 → 116,7 |
void after_thread_ran(void) |
{ |
after_thread_ran_arch(); |
rcu_run_callbacks(); |
} |
#ifdef CONFIG_FPU_LAZY |
207,7 → 209,7 |
interrupts_disable(); |
for (i = 0; i<RQ_COUNT; i++) { |
for (i = 0; i < RQ_COUNT; i++) { |
r = &CPU->rq[i]; |
spinlock_lock(&r->lock); |
if (r->n == 0) { |
377,7 → 379,8 |
void scheduler_separated_stack(void) |
{ |
int priority; |
DEADLOCK_PROBE_INIT(p_joinwq); |
ASSERT(CPU != NULL); |
if (THREAD) { |
406,6 → 409,8 |
spinlock_unlock(&THREAD->lock); |
delay(10); |
spinlock_lock(&THREAD->lock); |
DEADLOCK_PROBE(p_joinwq, |
DEADLOCK_THRESHOLD); |
goto repeat; |
} |
_waitq_wakeup_unsafe(&THREAD->join_wq, false); |
447,8 → 452,8 |
/* |
* Entering state is unexpected. |
*/ |
panic("tid%d: unexpected state %s\n", THREAD->tid, |
thread_states[THREAD->state]); |
panic("tid%llu: unexpected state %s\n", THREAD->tid, |
thread_states[THREAD->state]); |
break; |
} |
500,7 → 505,7 |
THREAD->state = Running; |
#ifdef SCHEDULER_VERBOSE |
printf("cpu%d: tid %d (priority=%d, ticks=%lld, nrdy=%ld)\n", |
printf("cpu%d: tid %llu (priority=%d, ticks=%llu, nrdy=%ld)\n", |
CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, |
atomic_get(&CPU->nrdy)); |
#endif |
568,7 → 573,7 |
* Searching least priority queues on all CPU's first and most priority |
* queues on all CPU's last. |
*/ |
for (j= RQ_COUNT - 1; j >= 0; j--) { |
for (j = RQ_COUNT - 1; j >= 0; j--) { |
for (i = 0; i < config.cpu_active; i++) { |
link_t *l; |
runq_t *r; |
609,8 → 614,8 |
*/ |
spinlock_lock(&t->lock); |
if ((!(t->flags & (THREAD_FLAG_WIRED | |
THREAD_FLAG_STOLEN))) && |
(!(t->fpu_context_engaged)) ) { |
THREAD_FLAG_STOLEN))) && |
(!(t->fpu_context_engaged))) { |
/* |
* Remove t from r. |
*/ |
636,7 → 641,7 |
*/ |
spinlock_lock(&t->lock); |
#ifdef KCPULB_VERBOSE |
printf("kcpulb%d: TID %d -> cpu%d, nrdy=%ld, " |
printf("kcpulb%d: TID %llu -> cpu%d, nrdy=%ld, " |
"avg=%nd\n", CPU->id, t->tid, CPU->id, |
atomic_get(&CPU->nrdy), |
atomic_get(&nrdy) / config.cpu_active); |
719,7 → 724,7 |
for (cur = r->rq_head.next; cur != &r->rq_head; |
cur = cur->next) { |
t = list_get_instance(cur, thread_t, rq_link); |
printf("%d(%s) ", t->tid, |
printf("%llu(%s) ", t->tid, |
thread_states[t->state]); |
} |
printf("\n"); |
/branches/rcu/kernel/generic/src/proc/task.c |
---|
41,6 → 41,7 |
#include <proc/uarg.h> |
#include <mm/as.h> |
#include <mm/slab.h> |
#include <atomic.h> |
#include <synch/spinlock.h> |
#include <synch/waitq.h> |
#include <arch.h> |
92,6 → 93,49 |
btree_create(&tasks_btree); |
} |
/** Kill all tasks except the current task. |
* |
*/ |
void task_done(void) |
{ |
task_t *t; |
do { /* Repeat until there are any tasks except TASK */ |
/* Messing with task structures, avoid deadlock */ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
t = NULL; |
link_t *cur; |
for (cur = tasks_btree.leaf_head.next; cur != &tasks_btree.leaf_head; cur = cur->next) { |
btree_node_t *node = list_get_instance(cur, btree_node_t, leaf_link); |
unsigned int i; |
for (i = 0; i < node->keys; i++) { |
if ((task_t *) node->value[i] != TASK) { |
t = (task_t *) node->value[i]; |
break; |
} |
} |
} |
if (t != NULL) { |
task_id_t id = t->taskid; |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
#ifdef CONFIG_DEBUG |
printf("Killing task %llu\n", id); |
#endif |
task_kill(id); |
} else { |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
} |
} while (t != NULL); |
} |
/** Create new task |
* |
140,11 → 184,8 |
/* |
* Increment address space reference count. |
* TODO: Reconsider the locking scheme. |
*/ |
mutex_lock(&as->lock); |
as->refcount++; |
mutex_unlock(&as->lock); |
atomic_inc(&as->refcount); |
spinlock_lock(&tasks_lock); |
166,15 → 207,8 |
task_destroy_arch(t); |
btree_destroy(&t->futexes); |
mutex_lock_active(&t->as->lock); |
if (--t->as->refcount == 0) { |
mutex_unlock(&t->as->lock); |
if (atomic_predec(&t->as->refcount) == 0) |
as_destroy(t->as); |
/* |
* t->as is destroyed. |
*/ |
} else |
mutex_unlock(&t->as->lock); |
free(t); |
TASK = NULL; |
382,7 → 416,7 |
link_t *cur; |
ipl_t ipl; |
/* Messing with thread structures, avoid deadlock */ |
/* Messing with task structures, avoid deadlock */ |
ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
408,7 → 442,7 |
char suffix; |
order(task_get_accounting(t), &cycles, &suffix); |
printf("%-6lld %-10s %-3ld %#10zx %#10zx %9llu%c %7zd " |
printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd " |
"%6zd", t->taskid, t->name, t->context, t, t->as, |
cycles, suffix, t->refcount, |
atomic_get(&t->active_calls)); |
495,7 → 529,7 |
ipc_cleanup(); |
futex_cleanup(); |
klog_printf("Cleanup of task %lld completed.", TASK->taskid); |
klog_printf("Cleanup of task %llu completed.", TASK->taskid); |
} |
/** Kernel thread used to kill the userspace task when its main thread exits. |
/branches/rcu/kernel/generic/src/proc/thread.c |
---|
94,7 → 94,7 |
btree_t threads_btree; |
SPINLOCK_INITIALIZE(tidlock); |
uint32_t last_tid = 0; |
thread_id_t last_tid = 0; |
static slab_cache_t *thread_slab; |
#ifdef ARCH_HAS_FPU |
238,6 → 238,7 |
cpu = CPU; |
if (t->flags & THREAD_FLAG_WIRED) { |
ASSERT(t->cpu != NULL); |
cpu = t->cpu; |
} |
t->state = Ready; |
496,7 → 497,7 |
ipl_t ipl; |
/* |
* Since the thread is expected to not be already detached, |
* Since the thread is expected not to be already detached, |
* pointer to it must be still valid. |
*/ |
ipl = interrupts_disable(); |
580,7 → 581,7 |
char suffix; |
order(t->cycles, &cycles, &suffix); |
printf("%-6zd %-10s %#10zx %-8s %#10zx %-3ld %#10zx " |
printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx " |
"%#10zx %9llu%c ", t->tid, t->name, t, |
thread_states[t->state], t->task, t->task->context, |
t->thread_code, t->kstack, cycles, suffix); |
636,12 → 637,11 |
/** Process syscall to create new thread. |
* |
*/ |
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name) |
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
uspace_arg_t *kernel_uarg; |
uint32_t tid; |
int rc; |
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN); |
658,12 → 658,14 |
t = thread_create(uinit, kernel_uarg, TASK, THREAD_FLAG_USPACE, namebuf, |
false); |
if (t) { |
tid = t->tid; |
thread_ready(t); |
return (unative_t) tid; |
} else { |
if (uspace_thread_id != NULL) |
return (unative_t) copy_to_uspace(uspace_thread_id, &t->tid, |
sizeof(t->tid)); |
else |
return 0; |
} else |
free(kernel_uarg); |
} |
return (unative_t) ENOMEM; |
} |
678,6 → 680,22 |
return 0; |
} |
/** Syscall for getting TID. |
* |
* @param uspace_thread_id Userspace address of 8-byte buffer where to store |
* current thread ID. |
* |
* @return 0 on success or an error code from @ref errno.h. |
*/ |
unative_t sys_thread_get_id(thread_id_t *uspace_thread_id) |
{ |
/* |
* No need to acquire lock on THREAD because tid |
* remains constant for the lifespan of the thread. |
*/ |
return (unative_t) copy_to_uspace(uspace_thread_id, &THREAD->tid, |
sizeof(THREAD->tid)); |
} |
/** @} |
*/ |