Ejemplo n.º 1
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
}
Ejemplo n.º 2
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;
}