Subversion Repositories HelenOS

Rev

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
}