Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sched: add task repetition functionality #279

Merged
merged 1 commit into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions common/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ static task_t *create_task(void) {
task->id = next_tid++;
task->gid = TASK_GROUP_ALL;
set_task_state(task, TASK_STATE_NEW);
atomic_set(&task->exec_count, 0);
set_task_once(task);

return task;
}
Expand Down Expand Up @@ -155,6 +157,20 @@ task_t *get_task_by_name(cpu_t *cpu, const char *name) {
return NULL;
}

static const char *task_repeat_string(task_repeat_t repeat) {
static char buf[20] = {0};

switch (repeat) {
case TASK_REPEAT_ONCE:
return "ONCE";
case TASK_REPEAT_LOOP:
return "LOOP";
default:
snprintf(buf, sizeof(buf), "%u times", repeat);
return buf;
}
}

int schedule_task(task_t *task, cpu_t *cpu) {
ASSERT(task);

Expand All @@ -165,7 +181,8 @@ int schedule_task(task_t *task, cpu_t *cpu) {

BUG_ON(get_task_state(task) != TASK_STATE_READY);

printk("CPU[%u]: Scheduling task %s[%u]\n", cpu->id, task->name, task->id);
printk("CPU[%u]: Scheduling task %s[%u] (%s)\n", cpu->id, task->name, task->id,
task_repeat_string(task->repeat));

spin_lock(&cpu->lock);
list_add_tail(&task->list, &cpu->task_queue);
Expand All @@ -182,7 +199,8 @@ static void run_task(task_t *task) {

wait_for_task_state(task, TASK_STATE_SCHEDULED);

printk("CPU[%u]: Running task %s[%u]\n", task->cpu->id, task->name, task->id);
if (atomic64_inc_return(&task->exec_count) == 0)
printk("CPU[%u]: Running task %s[%u]\n", task->cpu->id, task->name, task->id);

set_task_state(task, TASK_STATE_RUNNING);
if (task->type == TASK_TYPE_USER)
Expand Down Expand Up @@ -214,6 +232,24 @@ void wait_for_task_group(const cpu_t *cpu, task_group_t group) {
} while (busy);
}

void process_task_repeat(task_t *task) {
switch (task->repeat) {
case TASK_REPEAT_ONCE:
printk("%s task '%s' finished on CPU[%u] with result %ld (Run: %lu times)\n",
task->type == TASK_TYPE_KERNEL ? "Kernel" : "User", task->name,
task->cpu->id, task->result, atomic_read(&task->exec_count));
destroy_task(task);
break;
case TASK_REPEAT_LOOP:
set_task_state(task, TASK_STATE_SCHEDULED);
break;
default:
task->repeat--;
set_task_state(task, TASK_STATE_SCHEDULED);
break;
}
}

void run_tasks(cpu_t *cpu) {
task_t *task, *safe;

Expand All @@ -225,10 +261,7 @@ void run_tasks(cpu_t *cpu) {
list_for_each_entry_safe (task, safe, &cpu->task_queue, list) {
switch (task->state) {
case TASK_STATE_DONE:
printk("%s task '%s' finished on CPU[%u] with result %ld\n",
task->type == TASK_TYPE_KERNEL ? "Kernel" : "User", task->name,
cpu->id, task->result);
destroy_task(task);
process_task_repeat(task);
break;
case TASK_STATE_SCHEDULED:
run_task(task);
Expand Down
21 changes: 21 additions & 0 deletions include/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,20 @@ typedef enum task_type task_type_t;

typedef unsigned int tid_t;

typedef enum task_repeat {
TASK_REPEAT_LOOP = 0,
TASK_REPEAT_ONCE = 1,
} task_repeat_t;

struct task {
list_head_t list;

tid_t id;
task_type_t type;
task_group_t gid;
task_state_t state;
task_repeat_t repeat;
atomic64_t exec_count;

cpu_t *cpu;
void *stack;
Expand Down Expand Up @@ -110,4 +117,18 @@ static inline void execute_tasks(void) {
run_tasks(get_bsp_cpu());
wait_for_all_cpus();
}

static inline void set_task_repeat(task_t *task, task_repeat_t value) {
wipawel marked this conversation as resolved.
Show resolved Hide resolved
ASSERT(task);
task->repeat = value;
}

static inline void set_task_loop(task_t *task) {
set_task_repeat(task, TASK_REPEAT_LOOP);
}

static inline void set_task_once(task_t *task) {
set_task_repeat(task, TASK_REPEAT_ONCE);
}

#endif /* KTF_SCHED_H */
1 change: 1 addition & 0 deletions tests/unittests.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ int unit_tests(void *_unused) {
task_user1 = new_user_task("test1 user", test_user_task_func1, NULL);
task_user2 = new_user_task("test2 user", test_user_task_func2, NULL);

set_task_repeat(task1, 10);
schedule_task(task1, get_bsp_cpu());
schedule_task(task2, get_cpu(1));
schedule_task(task_user1, get_bsp_cpu());
Expand Down