diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index ac83e112..47c3c3f5 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -61,12 +61,48 @@ int multitasking_init(void); * @param ep Pointer to the entry function for the new task * @param arg Arguments the task shall start with * @param prio Desired priority of the new kernel task + * @param core_id Start the new task on the core with this id * * @return * - 0 on success * - -EINVAL (-22) on failure */ -int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio); +int create_kernel_task_on_core(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t core_id); + +/** @brief create a kernel task. + * + * @param id The value behind this pointer will be set to the new task's id + * @param ep Pointer to the entry function for the new task + * @param arg Arguments the task shall start with + * @param prio Desired priority of the new kernel task + * + * @return + * - 0 on success + * - -EINVAL (-22) on failure + */ +static inline int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) +{ + uint32_t core_id, flags; + + flags = irq_nested_disable(); + core_id = CORE_ID; + irq_nested_enable(flags); + + return create_kernel_task_on_core(id, ep, arg, prio, core_id); +} + +/** @brief Create a user level task. + * + * @param id The value behind this pointer will be set to the new task's id + * @param fname Filename of the executable to start the task with + * @param argv Pointer to arguments array + * @param core_id Start the new task on the core with this id + * + * @return + * - 0 on success + * - -EINVAL (-22) or -ENOMEM (-12)on failure + */ +int create_user_task_on_core(tid_t* id, const char* fame, char** argv, uint32_t core_id); /** @brief Create a user level task. * @@ -78,7 +114,16 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio); * - 0 on success * - -EINVAL (-22) or -ENOMEM (-12)on failure */ -int create_user_task(tid_t* id, const char* fame, char** argv); +static inline int create_user_task(tid_t* id, const char* fame, char** argv) +{ + uint32_t core_id, flags; + + flags = irq_nested_disable(); + core_id = CORE_ID; + irq_nested_enable(flags); + + return create_user_task_on_core(id, fame, argv, core_id); +} /** @brief Block current task until the child task is terminated * @param result The terminated child's return value diff --git a/kernel/tasks.c b/kernel/tasks.c index 3dbaba08..1f82c7b5 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -70,6 +70,10 @@ static runqueue_t runqueues[1] = { \ #endif #endif +#if MAX_CORES > 1 +extern atomic_int32_t cpu_online; +#endif + DEFINE_PER_CORE(task_t*, current_task, task_table+0); /** @brief helper function for the assembly code to determine the current task @@ -206,10 +210,12 @@ static void NORETURN do_exit(int arg) { spinlock_unlock(&curr_task->vma_lock); drop_pgd(); // delete page directory and its page tables - + +#if 0 if (atomic_int32_read(&curr_task->user_usage)) kprintf("Memory leak! Task %d did not release %d pages\n", curr_task->id, atomic_int32_read(&curr_task->user_usage)); +#endif curr_task->status = TASK_FINISHED; // decrease the number of active tasks @@ -252,15 +258,17 @@ void NORETURN abort(void) { * @param ep Pointer to the function the task shall start with * @param arg Arguments list * @param prio Desired priority of the new task + * @param core_id Start the new task on the core with this id + * * @return * - 0 on success * - -ENOMEM (-12) or -EINVAL (-22) on failure */ -static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) +static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t core_id) { task_t* curr_task; int ret = -ENOMEM; - unsigned int i, core_id; + uint32_t i; if (BUILTIN_EXPECT(!ep, 0)) return -EINVAL; @@ -271,7 +279,15 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) spinlock_irqsave_lock(&table_lock); - core_id = CORE_ID; +#if MAX_CORES > 1 + if (core_id >= atomic_int32_read(&cpu_online)) +#else + if (core_id > 0) +#endif + { + core_id = CORE_ID; + kprintf("Inavlid core id! Set id to %u!\n", core_id); + } curr_task = per_core(current_task); for(i=0; i MAX_PRIO) prio = NORMAL_PRIO; - return create_task(id, kernel_entry, kernel_args, prio); + return create_task(id, kernel_entry, kernel_args, prio, core_id); } #define MAX_ARGS (PAGE_SIZE - 2*sizeof(int) - sizeof(vfs_node_t*)) @@ -755,11 +771,13 @@ static int user_entry(void* arg) * @param id Pointer to the tid_t structure which shall be filles * @param fname Executable's path and filename * @param argv Arguments list + * @param core_id Start the new task on the core with this id + * * @return * - 0 on success * - -ENOMEM (-12) or -EINVAL (-22) on failure */ -int create_user_task(tid_t* id, const char* fname, char** argv) +int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint32_t core_id) { vfs_node_t* node; int argc = 0; @@ -797,7 +815,7 @@ int create_user_task(tid_t* id, const char* fname, char** argv) } /* create new task */ - return create_task(id, user_entry, load_args, NORMAL_PRIO); + return create_task(id, user_entry, load_args, NORMAL_PRIO, core_id); } /** @brief Used by the execve-Systemcall */ @@ -1129,10 +1147,6 @@ void update_load(void) } } -#if MAX_CORES > 1 -extern atomic_int32_t cpu_online; -#endif - void dump_load(void) { uint32_t i;