Esempio n. 1
0
void
start(void)
{

	sys_priority(PRIORITY);
	sys_share(SHARE);
	sys_yield();

	int i;

	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.
		//*cursorpos++ = PRINTCHAR;
		//call system call instead
		#ifndef __EXERCISE_8__
		sys_print(PRINTCHAR);
		#endif

		#ifdef __EXERCISE_8__
		while(atomic_swap(&spin_lock, 1) != 0){ //run 4ever until locked
			continue;
		}
		*cursorpos++ = PRINTCHAR;
		atomic_swap(&spin_lock, 0); //free
		#endif

		sys_yield();
	}

	// Yield forever.
	while (1)
		//sys_yield();
		sys_exit(0);
}
Esempio n. 2
0
void
input(envid_t ns_envid)
{
	binaryname = "ns_input";

	// LAB 6: Your code here:
	// 	- read a packet from the device driver
	//	- send it to the network server
	// Hint: When you IPC a page to the network server, it will be
	// reading from it for a while, so don't immediately receive
	// another packet in to the same physical page.
    uint8_t data[2048];
    int length, r;

    for (;;) {
        while ((length = sys_pkt_receive(data)) < 0)
            sys_yield();

        while (sys_page_alloc(0, &nsipcbuf, PTE_P | PTE_W | PTE_U) < 0)
            sys_yield();

        nsipcbuf.pkt.jp_len = length;
        memmove(nsipcbuf.pkt.jp_data, data, length);

        while (sys_ipc_try_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_P | PTE_W | PTE_U) < 0)
            sys_yield();
    }
}
void
start(void)
{
	int i;

	proc_priority(PRIORITYCHECK);
	proc_share(PRIORITYCHECK);
	sys_yield();

	for (i = 0; i < RUNCOUNT; i++) {
#ifdef USE_SYSTEM_SYNC
		// use a safe system call to print character to avoid a race condition
		proc_print(PRINTCHAR);
#else
		// use atomic_swap to get a lock
		while (atomic_swap(&lock, 1) !=0 ) {
			continue;
		}
		// Write characters to the console, yielding after each one.
		*cursorpos++ = PRINTCHAR;

		// use atomic_swap to release lock
		atomic_swap(&lock, 0);
#endif
		sys_yield();
	}

	// Yield forever.
	// while (1)
	// 	sys_yield();
	sys_exit(0);
}
Esempio n. 4
0
void
input(envid_t ns_envid)
{
	binaryname = "ns_input";

	// LAB 6: Your code here:
	// 	- read a packet from the device driver
	//	- send it to the network server
	// Hint: When you IPC a page to the network server, it will be
	// reading from it for a while, so don't immediately receive
	// another packet in to the same physical page.
	int i, r;
	int32_t length;
	struct jif_pkt *cpkt = pkt;
	
	for(i = 0; i < 10; i++)
		if ((r = sys_page_alloc(0, (void*)((uintptr_t)pkt + i * PGSIZE), PTE_P | PTE_U | PTE_W)) < 0)
			panic("sys_page_alloc: %e", r);
	
	i = 0;
	while(1) {
		while((length = sys_netpacket_recv((void*)((uintptr_t)cpkt + sizeof(cpkt->jp_len)), PGSIZE - sizeof(cpkt->jp_len))) < 0) {
			// cprintf("len: %d\n", length);
			sys_yield();
		}

		cpkt->jp_len = length;
		ipc_send(ns_envid, NSREQ_INPUT, cpkt, PTE_P | PTE_U);
		i = (i + 1) % 10;
		cpkt = (struct jif_pkt*)((uintptr_t)pkt + i * PGSIZE);
		sys_yield();
	}	
}
Esempio n. 5
0
u32_t sys_arch_mbox_fetch(struct sys_mbox** mbox, void** msg, u32_t timeout) {
	
	if(timeout) {
		timeout += timer_getms();	
		while(((*mbox)->count == 0) && (timeout > timer_getms()))
			sys_yield();
	}
	else
		while(((*mbox)->count == 0))
			sys_yield();

	if((*mbox)->count == 0)
		return SYS_ARCH_TIMEOUT;


	void* mx = (*mbox)->msg[0];
	memcpy(&(*mbox)->msg[0], &(*mbox)->msg[1], sizeof(void*) * (--(*mbox)->count));
	
	if(msg)
		*msg = mx;		


	if(timeout == 0)
		return SYS_ARCH_TIMEOUT;

	int s = timeout - (timeout - timer_getms());
	if(s < timeout)
		return s;

	return SYS_ARCH_TIMEOUT;
}
Esempio n. 6
0
File: ipc.c Progetto: gzs715/JOS
// Send 'val' (and 'pg' with 'perm', assuming 'pg' is nonnull) to 'toenv'.
// This function keeps trying until it succeeds.
// It should panic() on any error other than -E_IPC_NOT_RECV.
//
// Hint:
//   Use sys_yield() to be CPU-friendly.
//   If 'pg' is null, pass sys_ipc_recv a value that it will understand
//   as meaning "no page".  (Zero is not the right value.)
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
	// LAB 4: Your code here.
	int ret;
	void * srcva;
	if(pg == 0)
		srcva = (void*)UTOP;
	else
		srcva = pg;
	while(1)
	{
		ret = sys_ipc_try_send(to_env,val,srcva,perm);
		if(ret == 0 || ret == 1)		
		{
			//cprintf("return 0\n");
			sys_yield();
			break;
		}
		else if(ret == -E_IPC_NOT_RECV)
		{
			//cprintf("ipc not recv\n");
			sys_yield();
			continue;
		}
		else
			panic("error occur in ipc send:%e",ret);
	}
	//cprintf("return from ipc send\n");
	//panic("ipc_send not implemented");
}
Esempio n. 7
0
static void global_tests(uint32_t vcoreid)
{
	switch (test) {
		case TEST_YIELD_ALL:
			printf("Core %d yielding\n", vcoreid);
			sys_yield(0);
			// should be RUNNABLE_M now, amt_wanted == 1
			while(1);
		case TEST_SWITCH_TO_RUNNABLE_S:
			if (vcoreid == 2) {
				printf("Core %d trying to request 0/ switch to _S\n", vcoreid);
				udelay(3000000);
				vcore_request_more(0);
				// will only see this if we are scheduled()
				printf("Core %d back up!\n");
				printf("And exiting\n");
				exit(0);
			} 
			while(1);
		case TEST_CRAZY_YIELDS:
			udelay(300000*vcoreid);
			vcore_request_more(5);
			sys_yield(0);
			printf("should  never see me, unless you slip into *_S\n");
			break;
		case TEST_CONCURRENT_SYSCALLS:
			for (int i = 0; i < 10; i++) {
				for (int j = 0; j < 100; j++)
					sys_null();
				printf("Hello from vcore %d, iteration %d\n", vcoreid, i);
			}
			break;
	}
}
Esempio n. 8
0
void
start(void)
{
	int i;
	sys_share(SHARE);
	sys_priority(PRIORITY);
	#ifdef __EXERCISE_4A__ 
	sys_yield();//for 4a
	#endif
	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.
		//cursorpos++ = PRINTCHAR;
		//atomic_swap(uint32_t *addr, uint32_t val);
		#ifdef __EXERCISE_8__  // exercise 8 sync method
			sys_atomic_print(PRINTCHAR);
		#else // exercise 6 sync method
		while(atomic_swap(&lock,1)!= 0)
		{
			//return 0 means get the lock;
			continue;
		}
		*cursorpos++ = PRINTCHAR;
		atomic_swap(&lock,0);
		#endif
		sys_yield();
		
		//release the lock
	}

	// Yield forever.
	sys_exit(0);
}
Esempio n. 9
0
void
umain(int argc, char **argv)
{
	int i, j;
	int seen;
	envid_t parent = sys_getenvid();

	// Fork several environments
	for (i = 0; i < 20; i++)
		if (fork() == 0)
			break;
	if (i == 20) {
		sys_yield();
		return;
	}

	// Wait for the parent to finish forking
	while (envs[ENVX(parent)].env_status != ENV_FREE)
		asm volatile("pause");

	// Check that one environment doesn't run on two CPUs at once
	for (i = 0; i < 10; i++) {
		sys_yield();
		for (j = 0; j < 10000; j++)
			counter++;
	}

	if (counter != 10*10000)
		panic("ran on two CPUs at once (counter is %d)", counter);

	// Check that we see environments running on different CPUs
	cprintf("[%08x] stresssched on CPU %d\n", thisenv->env_id, thisenv->env_cpunum);

}
Esempio n. 10
0
void process_main(void) {
    while (1) {
        if (rand() % ALLOC_SLOWDOWN == 0) {
            if (sys_fork() == 0) {
                break;
            }
        } else {
            sys_yield();
        }
    }

    pid_t p = sys_getpid();
    srand(p);

    // The heap starts on the page right after the 'end' symbol,
    // whose address is the first address not allocated to process code
    // or data.
    heap_top = ROUNDUP((uint8_t*) end, PAGESIZE);

    // The bottom of the stack is the first address on the current
    // stack page (this process never needs more than one stack page).
    stack_bottom = ROUNDDOWN((uint8_t*) read_rsp() - 1, PAGESIZE);

    // Allocate heap pages until (1) hit the stack (out of address space)
    // or (2) allocation fails (out of physical memory).
    while (1) {
        int x = rand() % (8 * ALLOC_SLOWDOWN);
        if (x < 8 * p) {
            if (heap_top == stack_bottom || sys_page_alloc(heap_top) < 0) {
                break;
            }
            *heap_top = p;      /* check we have write access to new page */
            heap_top += PAGESIZE;
            if (console[CPOS(24, 0)]) {
                /* clear "Out of physical memory" msg */
                console_printf(CPOS(24, 0), 0, "\n");
            }
        } else if (x == 8 * p) {
            if (sys_fork() == 0) {
                p = sys_getpid();
            }
        } else if (x == 8 * p + 1) {
            sys_exit();
        } else {
            sys_yield();
        }
    }

    // After running out of memory
    while (1) {
        if (rand() % (2 * ALLOC_SLOWDOWN) == 0) {
            sys_exit();
        } else {
            sys_yield();
        }
    }
}
Esempio n. 11
0
void
umain(int argc, char **argv)
{
	envid_t env;

	cprintf("I am the parent.  Forking the child...\n");
	if ((env = fork()) == 0) {
		cprintf("I am the child.  Spinning...\n");
		while (1)
			/* do nothing */;
	}

	cprintf("I am the parent.  Running the child...\n");
	sys_yield();
	sys_yield();
	sys_yield();
	sys_yield();
	sys_yield();
	sys_yield();
	sys_yield();
	sys_yield();

	cprintf("I am the parent.  Killing the child...\n");
	sys_env_destroy(env);
}
Esempio n. 12
0
void
start(void)
{
	int i;

	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.
		*cursorpos++ = PRINTCHAR;
		sys_yield();
	}

	// Yield forever.
	while (1)
		sys_yield();
}
Esempio n. 13
0
void
start(void)
{
	int i;

	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.
		
		#ifndef __EXERCISE_8__
			// (exercise 6 code)
			sys_print(PRINTCHAR);
		

		#else
			// (exercise 8 code)
			// Implemented spinlock to remove race condition of printing for each process.
			while (atomic_swap(&spin_lock, 1) != 0)
				continue;

			*cursorpos++ = PRINTCHAR;
			atomic_swap(&spin_lock, 0);
		#endif

		sys_yield();
	}
	sys_exit(0);
	// // Yield forever.
	// while (1)
	// 	sys_yield();
}
Esempio n. 14
0
static ssize_t
devpipe_write(struct Fd *fd, const void *vbuf, size_t n)
{
	const uint8_t *buf;
	size_t i;
	struct Pipe *p;

	p = (struct Pipe*) fd2data(fd);
	if (debug)
		cprintf("[%08x] devpipe_write %08x %d rpos %d wpos %d\n",
			thisenv->env_id, uvpt[PGNUM(p)], n, p->p_rpos, p->p_wpos);

	buf = vbuf;
	for (i = 0; i < n; i++) {
		while (p->p_wpos >= p->p_rpos + sizeof(p->p_buf)) {
			// pipe is full
			// if all the readers are gone
			// (it's only writers like us now),
			// note eof
			if (_pipeisclosed(fd, p))
				return 0;
			// yield and see what happens
			if (debug)
				cprintf("devpipe_write yield\n");
			sys_yield();
		}
		// there's room for a byte.  store it.
		// wait to increment wpos until the byte is stored!
		p->p_buf[p->p_wpos % PIPEBUFSIZ] = buf[i];
		p->p_wpos++;
	}

	return i;
}
Esempio n. 15
0
static ssize_t
devpipe_read(struct Fd *fd, void *vbuf, size_t n)
{
	uint8_t *buf;
	size_t i;
	struct Pipe *p;

	p = (struct Pipe*)fd2data(fd);
	if (debug)
		cprintf("[%08x] devpipe_read %08x %d rpos %d wpos %d\n",
			thisenv->env_id, uvpt[PGNUM(p)], n, p->p_rpos, p->p_wpos);

	buf = vbuf;
	for (i = 0; i < n; i++) {
		while (p->p_rpos == p->p_wpos) {
			// pipe is empty
			// if we got any data, return it
			if (i > 0)
				return i;
			// if all the writers are gone, note eof
			if (_pipeisclosed(fd, p))
				return 0;
			// yield and see what happens
			if (debug)
				cprintf("devpipe_read yield\n");
			sys_yield();
		}
		// there's a byte.  take it.
		// wait to increment rpos until the byte is taken!
		buf[i] = p->p_buf[p->p_rpos % PIPEBUFSIZ];
		p->p_rpos++;
	}
	return i;
}
Esempio n. 16
0
void
umain(int argc, char **argv)
{
	envid_t ns_envid = sys_getenvid();
	int i, r;

	binaryname = "testoutput";

	output_envid = fork();
	if (output_envid < 0)
		panic("error forking");
	else if (output_envid == 0) {
		output(ns_envid);
		return;
	}

	for (i = 0; i < TESTOUTPUT_COUNT; i++) {
		if ((r = sys_page_alloc(0, pkt, PTE_P|PTE_U|PTE_W)) < 0)
			panic("sys_page_alloc: %e", r);
		pkt->jp_len = snprintf(pkt->jp_data,
				       PGSIZE - sizeof(pkt->jp_len),
				       "Packet %02d", i);
		cprintf("Transmitting packet %d\n", i);
		ipc_send(output_envid, NSREQ_OUTPUT, pkt, PTE_P|PTE_W|PTE_U);
		sys_page_unmap(0, pkt);
	}

	// Spin for a while, just in case IPC's or packets need to be flushed
	for (i = 0; i < TESTOUTPUT_COUNT*2; i++)
		sys_yield();
}
Esempio n. 17
0
static ssize_t
pipewrite(struct Fd *fd, const void *vbuf, size_t n, off_t offset)
{
	// Your code here.  See the lab text for a description of what 
	// pipewrite needs to do.  Write a loop that transfers one byte
	// at a time.  Unlike in read, it is not okay to write only some
	// of the data.  If the pipe fills and you've only copied some of
	// the data, wait for the pipe to empty and then keep copying.
	// If the pipe is full and closed, return 0.
	// Use _pipeisclosed to check whether the pipe is closed.

	struct Pipe *p;
	const uint8_t *buf;
	int i;

	USED(offset);

	p = (struct Pipe *)fd2data(fd);
	buf = vbuf;
	for (i = 0; i < n; i++) {
		while (p->p_wpos - p->p_rpos >= PIPEBUFSIZ) {
			if (_pipeisclosed(fd, p))
				return 0;
			sys_yield();
		}
		p->p_buf[p->p_wpos % PIPEBUFSIZ] = buf[i];
		p->p_wpos++;
	}
	return n;
}
Esempio n. 18
0
void
output(envid_t ns_envid)
{
	binaryname = "ns_output";
	int32_t reqType;
	int perm;	
	envid_t envid_sender;
	// LAB 6: Your code here:
	// 	- read a packet from the network server
	//	- send the packet to the device driver
	while(1)
	{
		perm = 0;
		//Read a packet from ns
		reqType = ipc_recv(&envid_sender, &nsipcbuf, &perm);
		//Check if ipc_recv has received correctly
		if(!(perm & PTE_P))
		{
			cprintf("Invalid request from network server[%08x]:no page",envid_sender);
			continue; 
		}
		if(reqType != NSREQ_OUTPUT)
		{
			cprintf("Invalid request from network server[%08x]:not a NSREQ_OUTPUT message",envid_sender);
			continue;
		}
		//Send packet to device driver.If packet send fails, give up CPU
		while(sys_send_packet(nsipcbuf.pkt.jp_data, nsipcbuf.pkt.jp_len) < 0)
			sys_yield();
	}
}
Esempio n. 19
0
void
start(void)
{
	int i;

	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.
		//*cursorpos++ = PRINTCHAR;

		// Atomic syscall version
		#ifdef __EXERCISE_6__
		sys_print(PRINTCHAR);
		#endif

		// Atomic lock version
		#ifdef __EXERCISE_8__
		while (atomic_swap(&lock, 1) != 0)
			continue;

		*cursorpos++ = PRINTCHAR;
		atomic_swap(&lock, 0);
		#endif

		sys_yield();
	}

	/*// Yield forever.
	while (1)
		sys_yield();*/

	sys_exit(0);
}
Esempio n. 20
0
void
start(void)
{
	int i;
	
	sys_set_priority(__PRIORITY__);
	sys_set_share(__SHARE__);
	sys_set_lottery_tickets(__LOTTERY_TICKETS__);

	for (i = 0; i < RUNCOUNT; i++) {
		// Write characters to the console, yielding after each one.

		#ifdef __PRINT_METHOD_LOCK__

		while(atomic_swap(&lock, 1) != 0) 
			continue;
		*cursorpos++ = PRINTCHAR;
		atomic_swap(&lock, 0);
		
		#else
		
		sys_atomic_print(PRINTCHAR);

		#endif

		sys_yield();
	}

	// Yield forever.
	//while (1)
	//	sys_yield();
	sys_exit(0);
}
Esempio n. 21
0
File: testkbd.c Progetto: yahu/JOS
void
umain(int argc, char **argv)
{
	int i, r;

	// Spin for a bit to let the console quiet
	for (i = 0; i < 10; ++i)
		sys_yield();

	close(0);
	if ((r = opencons()) < 0)
		panic("opencons: %e", r);
	if (r != 0)
		panic("first opencons used fd %d", r);
	if ((r = dup(0, 1)) < 0)
		panic("dup: %e", r);

	for(;;){
		char *buf;

		buf = readline("Type a line: ");
		if (buf != NULL)
			fprintf(1, "%s\n", buf);
		else
			fprintf(1, "(end of file received)\n");
        cprintf("read a line finish\n");
	}
}
Esempio n. 22
0
void
sleep(int sec)
{
	unsigned end = sys_time_msec() + sec * 1000;
	while (sys_time_msec() < end)
		sys_yield();
}
Esempio n. 23
0
static ssize_t
devpipe_read(struct Fd *fd, void *vbuf, size_t n)
{
	struct Pipe *p = (struct Pipe *) fd2data(fd);
	uint8_t *buf = (uint8_t *) vbuf;
	size_t i;

	for (i = 0; i < n; i++) {
		while (p->p_rpos == p->p_wpos) {
			// The pipe is currently empty.
			// If any data has been read, return it.
			// Otherwise, check for EOF; if not EOF, yield
			// and try again.
			if (i > 0)
				return i;
			else if (_pipeisclosed(fd, p))
				return 0;
			else
				sys_yield();
		}

		buf[i] = p->p_buf[p->p_rpos % PIPEBUFSIZ];
		// The increment must come AFTER we write to the buffer,
		// or the C compiler might update the pointer before writing
		// to the buffer!  In fact, we need a memory barrier here---
		// on some machines a memory barrier instruction.
		asm volatile("" : : : "memory");
		p->p_rpos++;
	}

	return i;
}
Esempio n. 24
0
File: ipc.c Progetto: dannoy/JOS
// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
// This function keeps trying until it succeeds.
// It should panic() on any error other than -E_IPC_NOT_RECV.
//
// Hint:
//   Use sys_yield() to be CPU-friendly.
//   If 'pg' is null, pass sys_ipc_recv a value that it will understand
//   as meaning "no page".  (Zero is not the right value.)
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
	// LAB 4: Your code here.
    //panic("ipc_send not implemented");
    /* lj */
    int ret = 0;
    void *addr = NULL;
    addr = pg ? pg : (void *)-1;
    //cprintf("%x->%x [%d]\n", thisenv->env_id, to_env, val);
    
    while (1) {
        if(-E_IPC_NOT_RECV == ret) {
            sys_yield();
        }

        ret = sys_ipc_try_send(to_env, val, addr, perm);

        if(0 == ret) {
            break;
        }
        else if(-E_IPC_NOT_RECV == ret) {
            //cprintf("%x continue\n", thisenv->env_id);
            continue;
        }
        else if(ret < 0) {
            panic("ipc_send error:%e", ret);
        }
    }
}
Esempio n. 25
0
// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
// This function keeps trying until it succeeds.
// It should panic() on any error other than -E_IPC_NOT_RECV.
//
// Hint:
//   Use sys_yield() to be CPU-friendly.
//   If 'pg' is null, pass sys_ipc_recv a value that it will understand
//   as meaning "no page".  (Zero is not the right value.)
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
	int r;

	if (pg == NULL)
		pg = (void *)UTOP;

	do {
		int r = sys_ipc_try_send(to_env, val, pg, perm);

		switch (r) {
		case 0:
		case 1:
			return;

		case -E_IPC_NOT_RECV:
			sys_yield();
			continue;

		default:
			panic("sys_ipc_try_send(%08x, %u, %08x, %d) failed: %e\n",
				to_env, val, pg, perm, r);
		}
	} while (1);
}
Esempio n. 26
0
u32_t sys_arch_sem_wait(struct sys_sem** sem, u32_t __timeout) {

	register u32_t timeout = __timeout;

	if(timeout)
		timeout += timer_getms();

#if CONFIG_SMP
	__sync_synchronize();
#endif
	(*sem)->lock--;

	while(
		((*sem)->lock < 0)
		&&
		(__timeout ? timeout > timer_getms() : 1)
	) sys_yield();


	if(__timeout == 0)
		return SYS_ARCH_TIMEOUT;
	
	int s = timeout - (timeout - timer_getms());
	if(s < timeout)
		return s;
	
	return SYS_ARCH_TIMEOUT;
}
Esempio n. 27
0
void
start(void)
{
	int i;

	for (i = 0; i < RUNCOUNT; i++) {
		#ifndef __EXERCISE_8__
		/* EXERCISE 6: use a system call to print characters *****************/
		sys_print(PRINTCHAR);
		#endif

		#ifdef __EXERCISE_8__
		/* EXERCISE 8: use a lock to prevent race conditions *****************/
		// spinlock until we obtain write lock
		while (atomic_swap(&spinlock, 1) != 0)
			continue;
		// write
		*cursorpos++ = PRINTCHAR;

		// release write lock
		atomic_swap(&spinlock, 0);
		#endif

		sys_yield();
	}

	// Yield forever.
	while (1)
		sys_exit(0);
}
Esempio n. 28
0
void vcore_entry(void)
{
	uint32_t vcoreid = vcore_id();

	if (vcoreid) {
		mcs_barrier_wait(&b, vcoreid);
		udelay(5000000);
		if (vcoreid == 1)
			printf("Proc %d's vcores are yielding\n", getpid());
		sys_yield(0);
	} else {
		/* trip the barrier here, all future times are in the loop */
		mcs_barrier_wait(&b, vcoreid);
		while (1) {
			udelay(15000000);
			printf("Proc %d requesting its cores again\n", getpid());
			begin = read_tsc();
			sys_resource_req(RES_CORES, max_vcores(), 1, REQ_SOFT);
			mcs_barrier_wait(&b, vcoreid);
			end = read_tsc();
			printf("Took %llu usec (%llu nsec) to get my yielded cores back.\n",
			       udiff(begin, end), ndiff(begin, end));
			printf("[T]:010:%llu:%llu\n",
			       udiff(begin, end), ndiff(begin, end));
		}
	}
	printf("We're screwed!\n");
	exit(-1);
}
Esempio n. 29
0
void vcore_entry(void)
{
	uint32_t vcoreid = vcore_id();

/* begin: stuff userspace needs to do to handle notifications */
	struct vcore *vc = &__procinfo.vcoremap[vcoreid];
	struct preempt_data *vcpd;
	vcpd = &__procdata.vcore_preempt_data[vcoreid];
	
	/* Lets try to restart vcore0's context.  Note this doesn't do anything to
	 * set the appropriate TLS.  On x86, this will involve changing the LDT
	 * entry for this vcore to point to the TCB of the new user-thread. */
	if (vcoreid == 0) {
		handle_events(vcoreid);
		set_tls_desc(core0_tls, 0);
		assert(__vcoreid == 0); /* in case anyone uses this */
		/* Load silly state (Floating point) too */
		pop_user_ctx(&vcpd->uthread_ctx, vcoreid);
		panic("should never see me!");
	}	
/* end: stuff userspace needs to do to handle notifications */

	/* all other vcores are down here */
	core1_up = TRUE;

	while (core1_up)
		cpu_relax();
	printf("Proc %d's vcore %d is yielding\n", getpid(), vcoreid);
	sys_yield(0);

	while(1);
}
Esempio n. 30
0
// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
// This function keeps trying until it succeeds.
// It should panic() on any error other than -E_IPC_NOT_RECV.
//
// Hint:
//   Use sys_yield() to be CPU-friendly.
//   If 'pg' is null, pass sys_ipc_recv a value that it will understand
//   as meaning "no page".  (Zero is not the right value.)
void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
	// LAB 4: Your code here.
	//panic("ipc_send not implemented");
	int result;

	if(pg == NULL)
	{
		result=sys_ipc_try_send(to_env, val, (void *)UTOP, perm);
	}
	else
	{
		result=sys_ipc_try_send(to_env, val, pg, perm);
	}
	
	while(result < 0)
	{
		if(result != -E_IPC_NOT_RECV)
		{
			panic ("ipc send error!");
		}
		
		sys_yield ();

		if(pg == NULL)
		{
			result=sys_ipc_try_send(to_env, val, (void *)UTOP, perm);
		}
		else
		{
			result=sys_ipc_try_send(to_env, val, pg, perm);
		}
	}
}