static void __vsep_func(
    void * const ptr)
{
  tid_t myid, nthreads;
  arg_t * arg;
  ctrl_t * ctrl;
  graph_t * graph;
  pid_t * where;
  pid_t ** dwhere;

  arg = ptr;

  ctrl = arg->ctrl;
  graph = arg->graph;
  where = arg->where;
  dwhere = arg->dwhere;

  myid = dlthread_get_id(ctrl->comm);
  nthreads = dlthread_get_nthreads(ctrl->comm);

  dlthread_barrier(ctrl->comm);

  if (nthreads > 1) {
    par_partition_pre(ctrl,graph);
  }

  dwhere[myid] = pid_alloc(graph->mynvtxs[myid]);

  par_partition_vertexseparator(ctrl,graph,dwhere);

  if (where) {
    __unify_where(dwhere,graph,where);
  }

  if (ctrl->verbosity >= MTMETIS_VERBOSITY_LOW) {
    dlthread_barrier(ctrl->comm);
    if (myid == 0) {
      partition_print_info(ctrl,graph,(pid_t const **)dwhere);
    }
    dlthread_barrier(ctrl->comm);
  }

  dl_free(dwhere[myid]);
}
void main() {
	kputs("--DEBUG-- Hello world from kernel!\n");
	
	unsigned long i;
	kernelsp[0]=(unsigned long)kernel_stack[1];
	for(i=1;i<MSIM_CPU_NUM;i++) {
		send(MSIM_MASTER_ID, 0, 0);
		kernelsp[i]=(unsigned long)kernel_stack[i+1];
		send(i, 1, (uint32_t)cpu_stack[i+1]);
		send(i, 0, (uint32_t)slave_main);
	}
	
	cur_pid=pid_alloc();
	write_c0_entryhi(cur_pid);
	sc_num=SYS_EXEC;
	sc_args[0]="init";
	sc_pid=cur_pid;
	
	for(;;) {
		write_c0_compare(0);
		switch(sc_num) {
			case SYS_PUTS:
				kputs(sc_args[0]);
				sc_ret=0;
				break;
			case SYS_FORK:
				sc_ret=kfork();
				break;
			case SYS_EXEC:
				sc_ret=kexec(sc_args[0]);
				break;
			case SYS_GETS:
				sc_ret=kgets(sc_args[0], sc_args[1]);
				break;
		}
		pcb[sc_pid].gpr[ORD_V0]=sc_ret;
		cur_pid=sc_pid;
		next_process;
		sc_num=SYS_NONE;
		__to_user();
	}
}
Пример #3
0
/*
 * Create a new thread based on an existing one.
 * The new thread has name NAME, and starts executing in function FUNC.
 * DATA1 and DATA2 are passed to FUNC.
 */
int
thread_fork(const char *name, 
	    void *data1, unsigned long data2,
	    void (*func)(void *, unsigned long),
	    pid_t *ret)
{
	struct thread *newguy;
	int s, result;

	/* Allocate a thread */
	newguy = thread_create(name);
	if (newguy==NULL) {
		return ENOMEM;
	}

	/* ASST1: Allocate a pid */
	result = pid_alloc(&newguy->t_pid);
	if (result != 0) {
	  kfree(newguy->t_name);
	  kfree(newguy);
	  return result;
	}

	/* Allocate a stack */
	newguy->t_stack = kmalloc(STACK_SIZE);
	if (newguy->t_stack==NULL) {
		pid_unalloc(newguy->t_pid); /* ASST1: cleanup pid on fail */
		kfree(newguy->t_name);
		kfree(newguy);
		return ENOMEM;
	}

	/* stick a magic number on the bottom end of the stack */
	newguy->t_stack[0] = 0xae;
	newguy->t_stack[1] = 0x11;
	newguy->t_stack[2] = 0xda;
	newguy->t_stack[3] = 0x33;

	/* Inherit the current directory */
	if (curthread->t_cwd != NULL) {
		VOP_INCREF(curthread->t_cwd);
		newguy->t_cwd = curthread->t_cwd;
	}

	/* ASST1: copy address space if there is one */
	if (curthread->t_vmspace != NULL) {
		result = as_copy(curthread->t_vmspace, &newguy->t_vmspace);
		if (result) {
			pid_unalloc(newguy->t_pid); 
			kfree(newguy->t_name);
			kfree(newguy->t_stack);
			kfree(newguy);			
			return ENOMEM;
		}
	}


	/* Set up the pcb (this arranges for func to be called) */
	md_initpcb(&newguy->t_pcb, newguy->t_stack, data1, data2, func);

	/* Interrupts off for atomicity */
	s = splhigh();

	/*
	 * Make sure our data structures have enough space, so we won't
	 * run out later at an inconvenient time.
	 */
	result = array_preallocate(sleepers, numthreads+1);
	if (result) {
		goto fail;
	}
	result = array_preallocate(zombies, numthreads+1);
	if (result) {
		goto fail;
	}

	/* Do the same for the scheduler. */
	result = scheduler_preallocate(numthreads+1);
	if (result) {
		goto fail;
	}

	/* Make the new thread runnable */
	result = make_runnable(newguy);
	if (result != 0) {
		goto fail;
	}

	/*
	 * Increment the thread counter. This must be done atomically
	 * with the preallocate calls; otherwise the count can be
	 * temporarily too low, which would obviate its reason for
	 * existence.
	 */
	numthreads++;

	/* Done with stuff that needs to be atomic */
	splx(s);

	/*
	 * Return new thread structure if it's wanted.  Note that
	 * using the thread structure from the parent thread should be
	 * done only with caution, because in general the child thread
	 * might exit at any time.
	 */
	if (ret != NULL) {
		*ret = newguy->t_pid; /* ASST1 return pid, not thread struct */
	} else {
		/* Not returning the pid... better detach the new thread */
		result = thread_detach(newguy->t_pid);
		assert(result == 0); /* can't fail. */
	}

	return 0;

 fail:
	splx(s);

	/* ASST1: cleanup pid and vmspace on fail */
	pid_unalloc(newguy->t_pid); 

	if (newguy->t_vmspace) {
		as_destroy(newguy->t_vmspace);
	}

	if (newguy->t_cwd != NULL) {
		VOP_DECREF(newguy->t_cwd);
	}
	kfree(newguy->t_stack);
	kfree(newguy->t_name);
	kfree(newguy);

	return result;
}