task_t* create_process(char* name, uint32_t eip, bool wants_stack) { Deprecated(); task_t* parent = current_task; //clone address space page_directory_t* cloned = vmm_clone_active_pdir(); //create new process task_t* task = kmalloc(sizeof(task_t)); memset(task, 0, sizeof(task_t)); task->name = strdup(name); task->id = next_pid++; task->page_dir = cloned; task->child_tasks = array_m_create(32); //task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); setup_fds(task); uint32_t current_eip = read_eip(); if (current_task == parent) { task->eip = current_eip; return task; } task->state = RUNNABLE; task->wake_timestamp = 0; task->vmem_slide = 0; task->windows = array_m_create(16); return task; }
void destroy_task(task_t* task) { Deprecated(); if (task == first_responder_task) { resign_first_responder(); } //close all pipes this process has opened for (int i = 0; i < FD_MAX; i++) { fd_entry entry = task->fd_table[i]; if (fd_empty(entry)) continue; if (entry.type == PIPE_TYPE) { pipe_t* pipe = (pipe_t*)entry.payload; pipe_close(pipe->fd); } } //remove task from queues and active list unlist_task(task); //printf_info("%s[%d] destroyed.", task->name, task->id); //free task's page directory free_directory(task->page_dir); array_m_destroy(task->child_tasks); std_stream_destroy(task); kfree(task->name); kfree(task); }
void iosent() { Deprecated(); while (1) { update_blocked_tasks(); //yield cpu to next task sys_yield(RUNNABLE); } }
void unblock_task(task_t* task) { Deprecated(); if (!tasking_is_active()) return; lock(mutex); task->state = RUNNABLE; task->block_context = NULL; unlock(mutex); }
static void tasking_critical_fail() { Deprecated(); char* msg = "One or more critical tasks died. axle has died.\n"; printf("%s\n", msg); //turn off interrupts kernel_begin_critical(); //sleep until next interrupt (infinite loop) asm("hlt"); //in case that ever finishes, infinite loop again while (1) {} }
task_t* task_with_pid(int pid) { Deprecated(); task_t* tmp = active_list; while (tmp != NULL) { if (tmp->id == pid) { return tmp; } tmp = tmp->next; } return NULL; }
void block_task_context(task_t* task, task_state reason, void* context) { Deprecated(); if (!tasking_is_active()) return; task->state = reason; task->block_context = context; //immediately switch tasks if active task was just blocked if (task == current_task) { task_switch_old(true); } }
static bool is_dead_task_crit(task_t* task) { Deprecated(); static char* crit_tasks[3] = { "idle", "iosentinel" }; for (uint32_t i = 0; i < sizeof(crit_tasks) / sizeof(crit_tasks[0]); i++) { if (!strcmp(crit_tasks[i], task->name)) { return true; } } return false; }
task_t* task_with_pid_auth(int pid) { Deprecated(); //first, ensure this task is allowed to do this! //permission to use task_with_pid is controlled by the PROC_MASTER_PERMISSION flag //only check if this is a non-kernel task //check for .bss segment as heuristic for whether this is an external program if (current_task->prog_break) { if (!(current_task->permissions & PROC_MASTER_PERMISSION)) { printf_err("%s[%d] is not authorized to use task_with_pid!", current_task->name, getpid()); return NULL; } } //operation permitted return task_with_pid(pid); }
void kill_task(task_t* task) { Deprecated(); bool show_died_message = !strcmp(task->name, "xserv"); if (show_died_message) { xserv_fail(); } if (is_dead_task_crit(task)) { tasking_critical_fail(); } if (task == first_responder_task) { resign_first_responder(); } block_task(task, ZOMBIE); }
static void setup_fds(task_t* task) { Deprecated(); memset(&task->fd_table, 0, sizeof(fd_entry) * FD_MAX); //initialize backing std stream task->std_stream = std_stream_create(); //set up stdin/out/err to point to task's std stream //this stream backs all 3 descriptors fd_entry std; std.type = STD_TYPE; std.payload = task->std_stream; task->fd_table[0] = std; task->fd_table[1] = std; task->fd_table[2] = std; }
void reap_task(task_t* tmp) { Deprecated(); if (tmp->state == ZOMBIE) { array_m* queue = array_m_lookup(queues, tmp->queue); int idx = array_m_index(queue, tmp); if (idx != ARR_NOT_FOUND) { printk("reap() unlisting %s\n", tmp->name); lock(mutex); array_m_remove(queue, idx); unlock(mutex); destroy_task(tmp); } else { //couldn't find task in the queue it said it was in //fall back on searching through each queue bool found = false; for (int i = 0; i < queues->size && !found; i++) { array_m* queue = array_m_lookup(queues, i); for (int j = 0; j < queues->size && !found; j++) { task_t* to_test = array_m_lookup(queue, j); if (to_test == tmp) { lock(mutex); array_m_remove(queue, j); unlock(mutex); destroy_task(tmp); found = true; break; } } } if (!found) { printf_err("Tried to reap task %s[%d] but it didn't exist in a queue", tmp->name, tmp->id); } } } }
* * Created on: Apr 5, 2013 * Author: tombr */ #include "MemoryTest.h" #include <capputils/attributes/DeprecatedAttribute.h> #include <gapputils/attributes/GroupAttribute.h> #include <cstdlib> namespace debug { #ifdef _RELEASE BeginPropertyDefinitions(MemoryTest, Deprecated("Only available in debug mode.")) #else BeginPropertyDefinitions(MemoryTest) #endif ReflectableBase(DefaultWorkflowElement<MemoryTest>) WorkflowProperty(Input, Input("In")) WorkflowProperty(Size, Group("Other parameter")) WorkflowProperty(Iterations, Group("Other parameter")) WorkflowProperty(Delay, Group("Other parameter")) WorkflowProperty(Output, Output("Out")) EndPropertyDefinitions MemoryTest::MemoryTest() : _Size(1), _Iterations(5), _Delay(1) {
void block_task(task_t* task, task_state reason) { Deprecated(); block_task_context(task, reason, NULL); }
void _kill() { Deprecated(); kill_task(current_task); }