Rev 2131 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2131 | Rev 2307 | ||
|---|---|---|---|
| Line 39... | Line 39... | ||
| 39 | #include <proc/thread.h> |
39 | #include <proc/thread.h> |
| 40 | #include <proc/task.h> |
40 | #include <proc/task.h> |
| 41 | #include <proc/uarg.h> |
41 | #include <proc/uarg.h> |
| 42 | #include <mm/as.h> |
42 | #include <mm/as.h> |
| 43 | #include <mm/slab.h> |
43 | #include <mm/slab.h> |
| - | 44 | #include <atomic.h> |
|
| 44 | #include <synch/spinlock.h> |
45 | #include <synch/spinlock.h> |
| 45 | #include <synch/waitq.h> |
46 | #include <synch/waitq.h> |
| 46 | #include <arch.h> |
47 | #include <arch.h> |
| 47 | #include <panic.h> |
48 | #include <panic.h> |
| 48 | #include <adt/btree.h> |
49 | #include <adt/btree.h> |
| Line 90... | Line 91... | ||
| 90 | { |
91 | { |
| 91 | TASK = NULL; |
92 | TASK = NULL; |
| 92 | btree_create(&tasks_btree); |
93 | btree_create(&tasks_btree); |
| 93 | } |
94 | } |
| 94 | 95 | ||
| - | 96 | /** Kill all tasks except the current task. |
|
| - | 97 | * |
|
| - | 98 | */ |
|
| - | 99 | void task_done(void) |
|
| - | 100 | { |
|
| - | 101 | task_t *t; |
|
| - | 102 | do { /* Repeat until there are any tasks except TASK */ |
|
| - | 103 | ||
| - | 104 | /* Messing with task structures, avoid deadlock */ |
|
| - | 105 | ipl_t ipl = interrupts_disable(); |
|
| - | 106 | spinlock_lock(&tasks_lock); |
|
| - | 107 | ||
| - | 108 | t = NULL; |
|
| - | 109 | link_t *cur; |
|
| - | 110 | for (cur = tasks_btree.leaf_head.next; cur != &tasks_btree.leaf_head; cur = cur->next) { |
|
| - | 111 | btree_node_t *node = list_get_instance(cur, btree_node_t, leaf_link); |
|
| - | 112 | ||
| - | 113 | unsigned int i; |
|
| - | 114 | for (i = 0; i < node->keys; i++) { |
|
| - | 115 | if ((task_t *) node->value[i] != TASK) { |
|
| - | 116 | t = (task_t *) node->value[i]; |
|
| - | 117 | break; |
|
| - | 118 | } |
|
| - | 119 | } |
|
| - | 120 | } |
|
| - | 121 | ||
| - | 122 | if (t != NULL) { |
|
| - | 123 | task_id_t id = t->taskid; |
|
| - | 124 | ||
| - | 125 | spinlock_unlock(&tasks_lock); |
|
| - | 126 | interrupts_restore(ipl); |
|
| - | 127 | ||
| - | 128 | #ifdef CONFIG_DEBUG |
|
| - | 129 | printf("Killing task %llu\n", id); |
|
| - | 130 | #endif |
|
| - | 131 | task_kill(id); |
|
| - | 132 | } else { |
|
| - | 133 | spinlock_unlock(&tasks_lock); |
|
| - | 134 | interrupts_restore(ipl); |
|
| - | 135 | } |
|
| - | 136 | ||
| - | 137 | } while (t != NULL); |
|
| - | 138 | } |
|
| 95 | 139 | ||
| 96 | /** Create new task |
140 | /** Create new task |
| 97 | * |
141 | * |
| 98 | * Create new task with no threads. |
142 | * Create new task with no threads. |
| 99 | * |
143 | * |
| Line 138... | Line 182... | ||
| 138 | 182 | ||
| 139 | ipl = interrupts_disable(); |
183 | ipl = interrupts_disable(); |
| 140 | 184 | ||
| 141 | /* |
185 | /* |
| 142 | * Increment address space reference count. |
186 | * Increment address space reference count. |
| 143 | * TODO: Reconsider the locking scheme. |
- | |
| 144 | */ |
187 | */ |
| 145 | mutex_lock(&as->lock); |
188 | atomic_inc(&as->refcount); |
| 146 | as->refcount++; |
- | |
| 147 | mutex_unlock(&as->lock); |
- | |
| 148 | 189 | ||
| 149 | spinlock_lock(&tasks_lock); |
190 | spinlock_lock(&tasks_lock); |
| 150 | 191 | ||
| 151 | ta->taskid = ++task_counter; |
192 | ta->taskid = ++task_counter; |
| 152 | btree_insert(&tasks_btree, (btree_key_t) ta->taskid, (void *) ta, NULL); |
193 | btree_insert(&tasks_btree, (btree_key_t) ta->taskid, (void *) ta, NULL); |
| Line 164... | Line 205... | ||
| 164 | void task_destroy(task_t *t) |
205 | void task_destroy(task_t *t) |
| 165 | { |
206 | { |
| 166 | task_destroy_arch(t); |
207 | task_destroy_arch(t); |
| 167 | btree_destroy(&t->futexes); |
208 | btree_destroy(&t->futexes); |
| 168 | 209 | ||
| 169 | mutex_lock_active(&t->as->lock); |
- | |
| 170 | if (--t->as->refcount == 0) { |
210 | if (atomic_predec(&t->as->refcount) == 0) |
| 171 | mutex_unlock(&t->as->lock); |
- | |
| 172 | as_destroy(t->as); |
211 | as_destroy(t->as); |
| 173 | /* |
- | |
| 174 | * t->as is destroyed. |
- | |
| 175 | */ |
- | |
| 176 | } else |
- | |
| 177 | mutex_unlock(&t->as->lock); |
- | |
| 178 | 212 | ||
| 179 | free(t); |
213 | free(t); |
| 180 | TASK = NULL; |
214 | TASK = NULL; |
| 181 | } |
215 | } |
| 182 | 216 | ||
| Line 380... | Line 414... | ||
| 380 | void task_print_list(void) |
414 | void task_print_list(void) |
| 381 | { |
415 | { |
| 382 | link_t *cur; |
416 | link_t *cur; |
| 383 | ipl_t ipl; |
417 | ipl_t ipl; |
| 384 | 418 | ||
| 385 | /* Messing with thread structures, avoid deadlock */ |
419 | /* Messing with task structures, avoid deadlock */ |
| 386 | ipl = interrupts_disable(); |
420 | ipl = interrupts_disable(); |
| 387 | spinlock_lock(&tasks_lock); |
421 | spinlock_lock(&tasks_lock); |
| 388 | 422 | ||
| 389 | printf("taskid name ctx address as cycles threads " |
423 | printf("taskid name ctx address as cycles threads " |
| 390 | "calls callee\n"); |
424 | "calls callee\n"); |
| Line 406... | Line 440... | ||
| 406 | 440 | ||
| 407 | uint64_t cycles; |
441 | uint64_t cycles; |
| 408 | char suffix; |
442 | char suffix; |
| 409 | order(task_get_accounting(t), &cycles, &suffix); |
443 | order(task_get_accounting(t), &cycles, &suffix); |
| 410 | 444 | ||
| 411 | printf("%-6lld %-10s %-3ld %#10zx %#10zx %9llu%c %7zd " |
445 | printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd " |
| 412 | "%6zd", t->taskid, t->name, t->context, t, t->as, |
446 | "%6zd", t->taskid, t->name, t->context, t, t->as, |
| 413 | cycles, suffix, t->refcount, |
447 | cycles, suffix, t->refcount, |
| 414 | atomic_get(&t->active_calls)); |
448 | atomic_get(&t->active_calls)); |
| 415 | for (j = 0; j < IPC_MAX_PHONES; j++) { |
449 | for (j = 0; j < IPC_MAX_PHONES; j++) { |
| 416 | if (t->phones[j].callee) |
450 | if (t->phones[j].callee) |
| Line 493... | Line 527... | ||
| 493 | * and no new threads can be created. |
527 | * and no new threads can be created. |
| 494 | */ |
528 | */ |
| 495 | 529 | ||
| 496 | ipc_cleanup(); |
530 | ipc_cleanup(); |
| 497 | futex_cleanup(); |
531 | futex_cleanup(); |
| 498 | klog_printf("Cleanup of task %lld completed.", TASK->taskid); |
532 | klog_printf("Cleanup of task %llu completed.", TASK->taskid); |
| 499 | } |
533 | } |
| 500 | 534 | ||
| 501 | /** Kernel thread used to kill the userspace task when its main thread exits. |
535 | /** Kernel thread used to kill the userspace task when its main thread exits. |
| 502 | * |
536 | * |
| 503 | * This thread waits until the main userspace thread (i.e. uninit) exits. |
537 | * This thread waits until the main userspace thread (i.e. uninit) exits. |