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 | } |