- add the support of "join_kernel_task"
git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@16 315a16e6-25f9-4109-90ae-ca3045a26c18
This commit is contained in:
parent
49177e8c9e
commit
b11c38d4af
3 changed files with 61 additions and 4 deletions
|
@ -37,13 +37,14 @@ extern "C" {
|
|||
typedef void* (STDCALL *entry_point_t)(void*);
|
||||
typedef unsigned int tid_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct task {
|
||||
unsigned char* top;
|
||||
unsigned int ip;
|
||||
tid_t id;
|
||||
mm_t mm;
|
||||
unsigned char* stack;
|
||||
size_t stack_size;
|
||||
unsigned char blocked_tasks[MAX_TASKS];
|
||||
unsigned char status;
|
||||
unsigned char idle;
|
||||
} task_t;
|
||||
|
|
|
@ -42,6 +42,18 @@ void* STDCALL foo(void* arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void* STDCALL join_test(void* arg)
|
||||
{
|
||||
int ret;
|
||||
tid_t id;
|
||||
|
||||
ret = create_kernel_task(&id, foo, "Hello from foo2\n", 0);
|
||||
kprintf("Wait for task %u: ret = %d\n", id, ret);
|
||||
ret = join_kernel_task(id);
|
||||
kprintf("Task %u finished: ret = %d\n", id, ret);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -70,7 +82,7 @@ int main(void)
|
|||
timer_set_frequency(TIMER_FREQ);
|
||||
|
||||
create_kernel_task(&id1, foo, "Hello from foo1\n", 8192);
|
||||
create_kernel_task(&id2, foo, "Hello from foo2\n", 0);
|
||||
create_kernel_task(&id2, join_test, NULL, 0);
|
||||
current_task->idle = 1;
|
||||
schedule();
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, size_t stack_size
|
|||
task_table[i].top = task_table[i].stack + stack_size - sizeof(size_t);
|
||||
task_table[i].ip = 0;
|
||||
task_table[i].id = i;
|
||||
memset(task_table[i].blocked_tasks, 0x00, sizeof(unsigned char)*MAX_TASKS);
|
||||
task_table[i].status = TASK_READY;
|
||||
task_table[i].idle = 0;
|
||||
|
||||
|
@ -110,7 +111,42 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, size_t stack_size
|
|||
|
||||
int join_kernel_task(tid_t id)
|
||||
{
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
irq_disable();
|
||||
|
||||
/*
|
||||
* idle tasks are not allowed to wait for another task
|
||||
* they should always run...
|
||||
*/
|
||||
if (BUILTIN_EXPECT(current_task->idle, 0))
|
||||
goto out;
|
||||
|
||||
/* a task is not able to wait for itself */
|
||||
if (BUILTIN_EXPECT(current_task->id == id, 0))
|
||||
goto out;
|
||||
|
||||
/* invalid id */
|
||||
if (BUILTIN_EXPECT(id >= MAX_TASKS, 0))
|
||||
goto out;
|
||||
|
||||
ret = 0;
|
||||
|
||||
/* task already finished */
|
||||
if (BUILTIN_EXPECT(task_table[id].status == TASK_INVALID, 0))
|
||||
goto out;
|
||||
|
||||
/* task already finished */
|
||||
if (BUILTIN_EXPECT(task_table[id].status == TASK_FINISHED, 0))
|
||||
goto out;
|
||||
|
||||
task_table[id].blocked_tasks[current_task->id] = 1;
|
||||
current_task->status = TASK_BLOCKED;
|
||||
out:
|
||||
irq_enable();
|
||||
schedule();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
task_t* get_new_task(void)
|
||||
|
@ -118,9 +154,17 @@ task_t* get_new_task(void)
|
|||
unsigned int i, new_id;
|
||||
|
||||
/* signalize that this task could be reuse */
|
||||
if (current_task->status == TASK_FINISHED)
|
||||
if (current_task->status == TASK_FINISHED) {
|
||||
current_task = TASK_INVALID;
|
||||
|
||||
/* wake up blocked tasks */
|
||||
for(i=0; i<MAX_TASKS; i++) {
|
||||
if ((current_task->blocked_tasks[i]) && (task_table[i].status == TASK_BLOCKED))
|
||||
task_table[i].status = TASK_READY;
|
||||
current_task->blocked_tasks[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=1; i <= MAX_TASKS; i++) {
|
||||
new_id = (current_task->id + i) % MAX_TASKS;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue