Rev 1573 | Rev 1580 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1573 | Rev 1579 | ||
|---|---|---|---|
| Line 45... | Line 45... | ||
| 45 | #include <ipc/ipc.h> |
45 | #include <ipc/ipc.h> |
| 46 | #include <security/cap.h> |
46 | #include <security/cap.h> |
| 47 | #include <memstr.h> |
47 | #include <memstr.h> |
| 48 | #include <print.h> |
48 | #include <print.h> |
| 49 | #include <elf.h> |
49 | #include <elf.h> |
| - | 50 | #include <errno.h> |
|
| 50 | #include <syscall/copy.h> |
51 | #include <syscall/copy.h> |
| 51 | 52 | ||
| 52 | #ifndef LOADED_PROG_STACK_PAGES_NO |
53 | #ifndef LOADED_PROG_STACK_PAGES_NO |
| 53 | #define LOADED_PROG_STACK_PAGES_NO 1 |
54 | #define LOADED_PROG_STACK_PAGES_NO 1 |
| 54 | #endif |
55 | #endif |
| 55 | 56 | ||
| 56 | SPINLOCK_INITIALIZE(tasks_lock); |
57 | SPINLOCK_INITIALIZE(tasks_lock); |
| 57 | btree_t tasks_btree; |
58 | btree_t tasks_btree; |
| 58 | static task_id_t task_counter = 0; |
59 | static task_id_t task_counter = 0; |
| 59 | 60 | ||
| - | 61 | static void ktask_cleanup(void *); |
|
| - | 62 | ||
| 60 | /** Initialize tasks |
63 | /** Initialize tasks |
| 61 | * |
64 | * |
| 62 | * Initialize kernel tasks support. |
65 | * Initialize kernel tasks support. |
| 63 | * |
66 | * |
| 64 | */ |
67 | */ |
| Line 92... | Line 95... | ||
| 92 | spinlock_initialize(&ta->lock, "task_ta_lock"); |
95 | spinlock_initialize(&ta->lock, "task_ta_lock"); |
| 93 | list_initialize(&ta->th_head); |
96 | list_initialize(&ta->th_head); |
| 94 | ta->as = as; |
97 | ta->as = as; |
| 95 | ta->name = name; |
98 | ta->name = name; |
| 96 | 99 | ||
| - | 100 | ta->refcount = 0; |
|
| - | 101 | ||
| 97 | ta->capabilities = 0; |
102 | ta->capabilities = 0; |
| - | 103 | ta->accept_new_threads = true; |
|
| 98 | 104 | ||
| 99 | ipc_answerbox_init(&ta->answerbox); |
105 | ipc_answerbox_init(&ta->answerbox); |
| 100 | for (i=0; i < IPC_MAX_PHONES;i++) |
106 | for (i=0; i < IPC_MAX_PHONES;i++) |
| 101 | ipc_phone_init(&ta->phones[i]); |
107 | ipc_phone_init(&ta->phones[i]); |
| 102 | if (ipc_phone_0) |
108 | if (ipc_phone_0) |
| Line 125... | Line 131... | ||
| 125 | interrupts_restore(ipl); |
131 | interrupts_restore(ipl); |
| 126 | 132 | ||
| 127 | return ta; |
133 | return ta; |
| 128 | } |
134 | } |
| 129 | 135 | ||
| - | 136 | /** Destroy task. |
|
| - | 137 | * |
|
| - | 138 | * @param t Task to be destroyed. |
|
| - | 139 | */ |
|
| - | 140 | void task_destroy(task_t *t) |
|
| - | 141 | { |
|
| - | 142 | } |
|
| - | 143 | ||
| 130 | /** Create new task with 1 thread and run it |
144 | /** Create new task with 1 thread and run it |
| 131 | * |
145 | * |
| 132 | * @param program_addr Address of program executable image. |
146 | * @param program_addr Address of program executable image. |
| 133 | * @param name Program name. |
147 | * @param name Program name. |
| 134 | * |
148 | * |
| Line 205... | Line 219... | ||
| 205 | btree_node_t *leaf; |
219 | btree_node_t *leaf; |
| 206 | 220 | ||
| 207 | return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf); |
221 | return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf); |
| 208 | } |
222 | } |
| 209 | 223 | ||
| - | 224 | /** Kill task. |
|
| - | 225 | * |
|
| - | 226 | * @param id ID of the task to be killed. |
|
| - | 227 | * |
|
| - | 228 | * @return 0 on success or an error code from errno.h |
|
| - | 229 | */ |
|
| - | 230 | int task_kill(task_id_t id) |
|
| - | 231 | { |
|
| - | 232 | ipl_t ipl; |
|
| - | 233 | task_t *ta; |
|
| - | 234 | thread_t *t; |
|
| - | 235 | link_t *cur; |
|
| - | 236 | ||
| - | 237 | ipl = interrupts_disable(); |
|
| - | 238 | spinlock_lock(&tasks_lock); |
|
| - | 239 | ||
| - | 240 | if (!(ta = task_find_by_id(id))) { |
|
| - | 241 | spinlock_unlock(&tasks_lock); |
|
| - | 242 | interrupts_restore(ipl); |
|
| - | 243 | return ENOENT; |
|
| - | 244 | } |
|
| - | 245 | ||
| - | 246 | spinlock_lock(&ta->lock); |
|
| - | 247 | ta->refcount++; |
|
| - | 248 | spinlock_unlock(&ta->lock); |
|
| - | 249 | ||
| - | 250 | t = thread_create(ktask_cleanup, NULL, ta, 0, "ktask_cleanup"); |
|
| - | 251 | ||
| - | 252 | spinlock_lock(&ta->lock); |
|
| - | 253 | ta->refcount--; |
|
| - | 254 | ||
| - | 255 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
|
| - | 256 | thread_t *thr; |
|
| - | 257 | bool sleeping = false; |
|
| - | 258 | ||
| - | 259 | thr = list_get_instance(cur, thread_t, th_link); |
|
| - | 260 | if (thr == t) |
|
| - | 261 | continue; |
|
| - | 262 | ||
| - | 263 | spinlock_lock(&thr->lock); |
|
| - | 264 | thr->interrupted = true; |
|
| - | 265 | if (thr->state == Sleeping) |
|
| - | 266 | sleeping = true; |
|
| - | 267 | spinlock_unlock(&thr->lock); |
|
| - | 268 | ||
| - | 269 | if (sleeping) |
|
| - | 270 | waitq_interrupt_sleep(thr); |
|
| - | 271 | } |
|
| - | 272 | ||
| - | 273 | thread_ready(t); |
|
| - | 274 | ||
| - | 275 | return 0; |
|
| - | 276 | } |
|
| - | 277 | ||
| 210 | /** Print task list */ |
278 | /** Print task list */ |
| 211 | void task_print_list(void) |
279 | void task_print_list(void) |
| 212 | { |
280 | { |
| 213 | link_t *cur; |
281 | link_t *cur; |
| 214 | ipl_t ipl; |
282 | ipl_t ipl; |
| Line 241... | Line 309... | ||
| 241 | } |
309 | } |
| 242 | 310 | ||
| 243 | spinlock_unlock(&tasks_lock); |
311 | spinlock_unlock(&tasks_lock); |
| 244 | interrupts_restore(ipl); |
312 | interrupts_restore(ipl); |
| 245 | } |
313 | } |
| - | 314 | ||
| - | 315 | /** Kernel thread used to cleanup the task. */ |
|
| - | 316 | void ktask_cleanup(void *arg) |
|
| - | 317 | { |
|
| - | 318 | /* |
|
| - | 319 | * TODO: |
|
| - | 320 | * Wait until it is save to cleanup the task (i.e. all other threads exit) |
|
| - | 321 | * and do the cleanup (e.g. close IPC communication and release used futexes). |
|
| - | 322 | * When this thread exits, the task refcount drops to zero and the task structure is |
|
| - | 323 | * cleaned. |
|
| - | 324 | */ |
|
| - | 325 | } |
|