Example #1
0
File: mem.c Project: abailly/solo5
void mem_init(struct multiboot_info *mb) {
    uint64_t max_avail = 0;
    multiboot_module_t *kernel;
    size_t i;

    /* the loader should really do this for us */
    clear_bss();

    for (i = 0; i < mb->mmap_length; i += sizeof(multiboot_memory_map_t)) {
        multiboot_memory_map_t *m;
        m = (multiboot_memory_map_t *)(mb->mmap_addr + i);
        max_addr = m->addr + m->len;
        if ( m->type == MULTIBOOT_MEMORY_AVAILABLE )
            max_avail = max_addr;
    }

    kernel = (multiboot_module_t *)((uint64_t)mb->mods_addr);


    kernel_start = kernel->mod_start;
    kernel_end = kernel->mod_end;
    page_table_area = (kernel_end & PAGE_MASK) + PAGE_SIZE;

    page_bitmap_init(mb->mmap_addr, mb->mmap_length);
    heap_start = (page_bitmap_area + PGBITS_SIZE(max_addr) + PAGE_SIZE - 1) 
        & PAGE_MASK;
    heap_top = heap_start;

    allocate_stack(max_avail - 8);
}
Example #2
0
PRIVATE void 
setup_context(int task_no, int max)
/* setup the thread context */
{
    char c;

    if (setjmp(thread_table[task_no].context)) {
	if (DEBUG_LEVEL >= 2) {
	    printf("Starting now thread %d\n", task_no);
	}
	kernel_mode=NO;
	thread_table[task_no].start_function();
	
	/* if the thread reaches this point it is actually exiting;
	   kill it */
	if (DEBUG_LEVEL > 0)
	    printf("Thread %d exhausts\n", task_no);
	kill_thread(task_no);
    }	
    else {  /* Pass to create next task */
	if (DEBUG_LEVEL >= 1)
	    printf("Thread %d created\n", task_no);
	thread_table[task_no].stack_start = &c;
	allocate_stack(task_no+1, max); /* this never returns...*/
    }
}
Example #3
0
PUBLIC void 
initialize_threads(void)
/* build the thread stacks and their context structures */
{
    struct thread* t;

    if (!setjmp(home)) 
	allocate_stack(0, MAX_THREADS);

    /* save the context in order to restore it at the top of the
       stack if the thread dies -- to recover stack space */
    for_all_threads(t) {
	copy_context(t->context, t->original_context);
    }
    alive = 0;
    sleeping = 0;
    to_alarm = 0;
}    
Example #4
0
yarn_t yarn_new ( void (*routine)(void*), void* udata, int nice )
{
	// grab memory
	yarn* active_yarn;
	yarn_t pid;
	//prepare_context(0);
	pool* p = get_yarn_pool();
	active_yarn = (yarn*)pool_allocate(p);
	assert(active_yarn);
	// prepare the context
	init_context(&active_yarn->context);
	// set up stack and such
	active_yarn->stackBase = allocate_stack(&(active_yarn->context));
	// run yarn_context_make to direct it over to the bootstrap
	prepare_context(active_yarn, routine, udata);
	// insert it into the yarn list
	pid = list_insert(active_yarn, nice);
	if (live)
		master_sched_schedule(pid, prio_lookup(nice));
	return pid;
}
Example #5
0
uint32_t exec_elf(const char* name) {
	fs_node_t* file = finddir(fs_root, name);
	open(file, 1, 0);

	// disable interrupts
	asm volatile("cli");

	// save directory and create one for new task
	page_directory_t* old_dir = current_directory;
	page_directory_t* new_dir = clone_directory(old_dir);

	// switch to new directory (this is where we set up process)
	switch_page_directory(new_dir);

	// load elf and get entry point
	uint32_t entry = load_elf_binary(file);

	// setup stack
	uint32_t stack = (uint32_t) allocate_stack(THREAD_STACK_SIZE);

	// create scheduling structures
	thread_t* new_thread = create_thread((int(*)(void*)) entry, 0,
			(uint32_t*) stack, THREAD_STACK_SIZE);
	task_t* new_task = create_task(new_thread, new_dir);
	schedule_add_task(new_task);

	// switch back to parents directory
	switch_page_directory(old_dir);

	// close executable image
	close(file);

	// reenable interrupts
	asm volatile("sti");

	// like in fork return child pid
	return new_task->pid;
}
Example #6
0
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
}
Example #7
0
uint32_t exec_thread(int(*fn)(void*), void* arg) {
	thread_t * new_thread = create_thread(fn, arg,
			allocate_stack(THREAD_STACK_SIZE), THREAD_STACK_SIZE);
	task_add_thread(current_task, new_thread);
	return new_thread->tid;
}
Example #8
0
/**
 * \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;
}