static void yarn_processor ( unsigned long procID ) { // this is the main routine run by each thread struct sigaction sa; void* stackRoot; volatile int breakProcessor = 0; int rc; unsigned deadSleepTime = YARNS_DEAD_SLEEP_TIME; // init the thread yarn data TTDINIT(); TTDGET(); // make sure it initted properly assert(&TTD); // repeatedly ask the scheduler for the next job scheduler_job activeJob; #ifdef BASE_CONTEXT_NEEDS_STACK stackRoot = allocate_stack(&(TTD.sched_context)); #endif #if YARNS_SYNERGY == YARNS_SYNERGY_PREEMPTIVE sa.sa_sigaction = (void (*)(int, struct __siginfo *, void *))preempt_signal_handler; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGUSR2); sigaction(SIGUSR2, &sa, 0); #endif activeJob.pid = 0; activeJob.runtime = 0; activeJob.data = 0; activeJob.next = 0; activeJob.priority = SCHED_PRIO_NORMAL; while (!breakProcessor) { TTD.shouldSuspend = 0; if (procID == wgProcResponsibility) { wait_graph_lock(wg); wait_graph_time_process(wg); wait_graph_unlock(wg); wgProcResponsibility++; wgProcResponsibility %= coreCount; } master_sched_select(procID, &activeJob); if (activeJob.pid == 0) { usleep(deadSleepTime); deadSleepTime += (deadSleepTime / 2); continue; } DEBUG("job %lu @ proc %d (rt: %lu us)\n", activeJob.pid, (int)procID, activeJob.runtime); if (activeJob.pid >= maxpid) { DEBUG("got pid %lu which is out-of-bound!\n", activeJob.pid); usleep(deadSleepTime); continue; } if (!PTABLE(activeJob.pid)) { DEBUG("got dead pid %lu\n", activeJob.pid); usleep(deadSleepTime); continue; } // set all the stuff up TTD.yarn_current = PTABLE(activeJob.pid); TTD.start_time = yarns_time(); TTD.next = 0; TTD.runtime = activeJob.runtime; // swap contexts DEBUG("yarn_context_swap to yarn: %p\n", TTD.yarn_current); #if YARNS_SYNERGY == YARNS_SYNERGY_PREEMPTIVE preempt(yarns_time() + activeJob.runtime, procID); preempt_enable(); #endif rc = yarn_context_swap(&(TTD.sched_context), &(TTD.yarn_current->context)); #if YARNS_SYNERGY == YARNS_SYNERGY_PREEMPTIVE preempt_disable(); #endif activeJob.next = TTD.next; // check it actually worked if (rc == 0) perror("yarn_context_swap failed"); // set the runtime #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif activeJob.runtime = MIN(TTD.runtime, activeJob.runtime); // if we're unscheduling, yfree up memory if (TTD.runtime == UNSCHEDULE) { master_sched_unschedule(procID, &activeJob); deallocate_stack(TTD.yarn_current->stackBase); pool_free(get_yarn_pool(), TTD.yarn_current); } else if (TTD.shouldSuspend) { TTD.yarn_current->isSuspended = 1; TTD.yarn_current->suspensionCore = procID; memcpy(&(TTD.yarn_current->suspensionJob), &activeJob, sizeof(activeJob)); } else { master_sched_reschedule(procID, &activeJob); } deadSleepTime = YARNS_DEAD_SLEEP_TIME; } #ifdef BASE_CONTEXT_NEEDS_STACK deallocate_stack(stackRoot); #endif }
/** * \private * create a pcb with all the needed value at the specified location */ uint32_t create_proc(char *name, uint32_t prio, uint32_t argc, char **params) { uint32_t *i, j; int32_t pid; pcb *p; prgm *prg; //kdebug_println("Create process in"); if (name == NULL) return NULLPTR; if (prio > MAX_PRI || prio < MIN_PRI) return INVARG; if (pcb_counter <= MAXPCB) { /* * Allocate a pcb */ p = alloc_pcb(); if (p == NULL) return OUTOMEM; /* * Reset the pcb */ pcb_reset(p); /* * Check that the program exist */ prg = search_prgm(name); if (prg == NULL) return INVARG; /* * Set the name */ pcb_set_name(p, name); /* * init the program counter */ pcb_set_epc(p, (uint32_t) prg->address); /* * get a pid */ pid = get_next_pid(); if (pid < 0) return pid; /* contain an error code */ pcb_set_pid(p, pid); /* set the pid */ pcb_set_pri(p, prio); /* set the priority */ /* * Set the supervisor of the process, which is the one we ask for the creation * or -1 if the system ask. * This value is in the global variable current_pcb */ if (current_pcb != NULL) { pcb_set_supervisor(p, pcb_get_pid(current_pcb)); pcb_set_supervised(current_pcb, pid); } else pcb_set_supervisor(p, -1); /* <<<<<<< HEAD:src/kernel/kprocess.c <<<<<<< HEAD:src/kernel/kprocess.c * Set the parameters of the function */ //p->registers.a_reg[0] = (params == NULL) ? 0 : stoi(get_arg(params, 0)) + 1; //p->registers.a_reg[1] = (uint32_t) params; /* the adresse of the first arg */ if (params != NULL) { p->registers.a_reg[0] = argc + 1; p->registers.a_reg[1] = (uint32_t) params; } else { p->registers.a_reg[0] = 0; p->registers.a_reg[1] = 0; } /* ======= >>>>>>> 3e4887fd7d8130975ae6c220ed2077f5f2538be9:src/kernel/kprocess.c * Set the stack pointer ======= * Set the stack pointer >>>>>>> ef0b08729fd10e82db039bea92d2ce232b3a027b:src/kernel/kprocess.c */ i = allocate_stack(pcb_get_pid(p)); if (i == NULL) return OUTOMEM; /* * We add the arg on the stack */ //kprint("sp set\n"); if (params != NULL) { //kprint((char *) params); //kprint("params not null\n"); //kprint(itos((uint32_t) i, c)); //kprint("\n"); i = (uint32_t *) ((uint32_t) i - (ARG_SIZE * (argc + 1) * sizeof(char))); /* set the sp after the arg */ //kprint(itos((uint32_t) i, c)); //kprint("\n"); pcb_set_sp(p, (uint32_t) i); /* set the stack pointer */ for (j = 0; j < (argc + 1) * (ARG_SIZE * sizeof(char) / sizeof(uint32_t)); j++) { //kprint("Copy params\n"); *i = (uint32_t) * params; //kprint("Param copied\n"); //i += ARG_SIZE * sizeof(char); i++; (uint32_t *) params++; } //kprint((char *) pcb_get_sp(p)); } else pcb_set_sp(p, (uint32_t) i); //kprint("copy arg done\n"); /* * Set the parameters of the function * The begin of the parameters are pointed by the stack pointer */ if (params != NULL) { p->registers.a_reg[0] = argc + 1; p->registers.a_reg[1] = (uint32_t) pcb_get_sp(p); } else { p->registers.a_reg[0] = 0; p->registers.a_reg[1] = 0; } /* * Set the state */ pcb_set_state(p, READY); /* * Set the last error */ pcb_set_error(p, OMGROXX); /* * The pcb is no more empty */ pcb_set_empty(p, FALSE); /* * Now we can add the pcb to the ready list */ if (pls_add(&plsready, p) == OUTOMEM) { /* * Adding fail, don't forget to dealloc every allocated stuff */ deallocate_stack(pcb_get_pid(p)); pcb_reset(p); return OUTOMEM; } /* * Everything goes well, we add one to the pcb_counter */ pcb_counter++; } else return OUTOMEM; //kdebug_println("Create process out"); return pid; }