Пример #1
0
/**
 * <Ring 1> Main loop of task TTY.
 *****************************************************************************/
PUBLIC void task_tty()
{
	TTY *	tty;
	MESSAGE msg;

	init_keyboard();

	for (tty = TTY_FIRST; tty < TTY_END; tty++)
		init_tty(tty);

	select_console(0);

	while (1) {
		for (tty = TTY_FIRST; tty < TTY_END; tty++) {
			do {
				tty_dev_read(tty);
				tty_dev_write(tty);
			} while (tty->ibuf_cnt);
		}

		send_recv(RECEIVE, ANY, &msg);

		int src = msg.source;
		assert(src != TASK_TTY);

		TTY* ptty = &tty_table[msg.DEVICE];

		switch (msg.type) {
		case DEV_OPEN:
			reset_msg(&msg);
			msg.type = SYSCALL_RET;
			send_recv(SEND, src, &msg);
			break;
		case DEV_READ:
			tty_do_read(ptty, &msg);
			break;
		case DEV_WRITE:
			tty_do_write(ptty, &msg);
			break;
		case HARD_INT:
			/**
			 * waked up by clock_handler -- a key was just pressed
			 * @see clock_handler() inform_int()
			 */
			key_pressed = 0;
			continue;
		default:
			dump_msg("TTY::unknown msg", &msg);
			break;
		}
	}
}
Пример #2
0
/**
 * Main loop of HD driver.
 * 
 *****************************************************************************/
PUBLIC void task_hd()
{
	MESSAGE msg;
	//init_dma();
	init_hd();
	
	while (1) {
		reset_msg(&msg);
		send_recv(RECEIVE, ANY, &msg);

		int src = msg.source;

		switch (msg.type) {
		case DEV_OPEN:
			hd_open(msg.DEVICE);
			break;
		case DEV_CLOSE:
			hd_close(msg.DEVICE);
			break;
		case DEV_READ:
		case DEV_WRITE:
			hd_rdwt(&msg);
			break;
		case DEV_IOCTL:
			hd_ioctl(&msg);
			break;
		case DEV_DMA:
			
			break;
		default:
			dump_msg("HD driver::unknown msg", &msg);
			spin("FS::main_loop (invalid msg.type)");
			break;
		}

		send_recv(SEND, src, &msg);
	}
}
Пример #3
0
PUBLIC void task_clock()
{

	MESSAGE m;
	int result;
	
	while(TRUE)
	{	
		reset_msg(&m);
		send_recv(RECEIVE,ANY,&m);
	
		switch(m.type)
		{
			case  HARD_INT:
				
				result=do_clockclick();
				break;
			default:
				printf("CLOCK: illegal request from ...%d",m.source);
		}
	}

}
Пример #4
0
/**
 * <Ring 0> Try to get a message from the src proc. If src is blocked sending
 * the message, copy the message from it and unblock src. Otherwise the caller
 * will be blocked.
 * 
 * @param current The caller, the proc who wanna receive.
 * @param src     From whom the message will be received.
 * @param m       The message ptr to accept the message.
 * 
 * @return  Zero if success.
 *****************************************************************************/
PRIVATE int msg_receive(struct proc* current, int src, MESSAGE* m)
{
	struct proc* p_who_wanna_recv = current; /**
						  * This name is a little bit
						  * wierd, but it makes me
						  * think clearly, so I keep
						  * it.
						  */
	struct proc* p_from = 0; /* from which the message will be fetched */
	struct proc* prev = 0;
	int copyok = 0;

	assert(proc2pid(p_who_wanna_recv) != src);

	if ((p_who_wanna_recv->has_int_msg) &&
	    ((src == ANY) || (src == INTERRUPT))) {
		/* There is an interrupt needs p_who_wanna_recv's handling and
		 * p_who_wanna_recv is ready to handle it.
		 */

		MESSAGE msg;
		reset_msg(&msg);
		msg.source = INTERRUPT;
		msg.type = HARD_INT;
		assert(m);
		phys_copy(va2la(proc2pid(p_who_wanna_recv), m), &msg,
			  sizeof(MESSAGE));

		p_who_wanna_recv->has_int_msg = 0;

		assert(p_who_wanna_recv->p_flags == 0);
		assert(p_who_wanna_recv->p_msg == 0);
		assert(p_who_wanna_recv->p_sendto == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);

		return 0;
	}


	/* Arrives here if no interrupt for p_who_wanna_recv. */
	if (src == ANY) {
		/* p_who_wanna_recv is ready to receive messages from
		 * ANY proc, we'll check the sending queue and pick the
		 * first proc in it.
		 */
		if (p_who_wanna_recv->q_sending) {
			p_from = p_who_wanna_recv->q_sending;
			copyok = 1;

			assert(p_who_wanna_recv->p_flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
			assert(p_who_wanna_recv->p_sendto == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);
			assert(p_from->p_flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->p_recvfrom == NO_TASK);
			assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
		}
	}
	else {
		/* p_who_wanna_recv wants to receive a message from
		 * a certain proc: src.
		 */
		p_from = &proc_table[src];

		if ((p_from->p_flags & SENDING) &&
		    (p_from->p_sendto == proc2pid(p_who_wanna_recv))) {
			/* Perfect, src is sending a message to
			 * p_who_wanna_recv.
			 */
			copyok = 1;

			struct proc* p = p_who_wanna_recv->q_sending;
			assert(p); /* p_from must have been appended to the
				    * queue, so the queue must not be NULL
				    */
			while (p) {
				assert(p_from->p_flags & SENDING);
				if (proc2pid(p) == src) { /* if p is the one */
					p_from = p;
					break;
				}
				prev = p;
				p = p->next_sending;
			}

			assert(p_who_wanna_recv->p_flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
			assert(p_who_wanna_recv->p_sendto == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);
			assert(p_from->p_flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->p_recvfrom == NO_TASK);
			assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
		}
	}

	if (copyok) {
		/* It's determined from which proc the message will
		 * be copied. Note that this proc must have been
		 * waiting for this moment in the queue, so we should
		 * remove it from the queue.
		 */
		if (p_from == p_who_wanna_recv->q_sending) { /* the 1st one */
			assert(prev == 0);
			p_who_wanna_recv->q_sending = p_from->next_sending;
			p_from->next_sending = 0;
		}
		else {
			assert(prev);
			prev->next_sending = p_from->next_sending;
			p_from->next_sending = 0;
		}

		assert(m);
		assert(p_from->p_msg);
		/* copy the message */
		phys_copy(va2la(proc2pid(p_who_wanna_recv), m),
			  va2la(proc2pid(p_from), p_from->p_msg),
			  sizeof(MESSAGE));

		p_from->p_msg = 0;
		p_from->p_sendto = NO_TASK;
		p_from->p_flags &= ~SENDING;
		unblock(p_from);
	}
	else {  /* nobody's sending any msg */
		/* Set p_flags so that p_who_wanna_recv will not
		 * be scheduled until it is unblocked.
		 */
		p_who_wanna_recv->p_flags |= RECEIVING;

		p_who_wanna_recv->p_msg = m;

		if (src == ANY)
			p_who_wanna_recv->p_recvfrom = ANY;
		else
			p_who_wanna_recv->p_recvfrom = proc2pid(p_from);

		block(p_who_wanna_recv);

		assert(p_who_wanna_recv->p_flags == RECEIVING);
		assert(p_who_wanna_recv->p_msg != 0);
		assert(p_who_wanna_recv->p_recvfrom != NO_TASK);
		assert(p_who_wanna_recv->p_sendto == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);
	}

	return 0;
}
Пример #5
0
/**************************************************************************************************
 * 					msg_receive
 **************************************************************************************************
 * <Ring 0> Try to get a message from the src proc.
 * If src is blocked sending the message, copy the message from it and unblock src.
 * Otherwise the caller will be blocked.
 *
 * @param current	The caller, the proc who wanna receive.
 * @param src		From whom the message will be received.
 * @param m		Pointer to the MESSAGE struct.
 *
 * @return		0 if success.
 *************************************************************************************************/
PRIVATE int msg_receive(PROCESS* current, int src, MESSAGE* m){
	PROCESS* p_who_wanna_recv	= current;
	PROCESS* p_from			= 0;
	PROCESS* prev			= 0;	/* the prior of p_from in the sending queue. */

	int copyok			= FALSE;
	
	assert(proc2pid(p_who_wanna_recv) != src);

	/*
	 * There is an interrupt needs p_who_wanna_recv's handling and p_who_wanna_recv is ready
	 * to handle it.
	 */
	if((p_who_wanna_recv->has_int_msg) && ((src == ANY) || (src == INTERRUPT))){
		MESSAGE msg;
		reset_msg(&msg);
		msg.source	= INTERRUPT;
		msg.type	= HARD_INT;

		assert(m);

		phys_copy(va2la(proc2pid(p_who_wanna_recv), m), &msg, sizeof(MESSAGE));
		
		p_who_wanna_recv->has_int_msg = 0;

		assert(p_who_wanna_recv->flags == 0);
		assert(p_who_wanna_recv->p_msg == 0);
		assert(p_who_wanna_recv->send_to == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);

		return 0;
	}

	/*
	 * Arrive here if no interrupt for p_who_wanna_recv.
	 *
	 * p_who_wanna_recv is ready to receive messages from ANY proc, we'll check the sending queue
	 * and pick the first proc in it.
	 */
	if(src == ANY){
		if(p_who_wanna_recv->q_sending){
			p_from		= p_who_wanna_recv->q_sending;
			copyok		= TRUE;

			assert(p_who_wanna_recv->flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->recv_from == NO_TASK);
			assert(p_who_wanna_recv->send_to == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);

			assert(p_from->flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->recv_from == NO_TASK);
			assert(p_from->send_to == proc2pid(p_who_wanna_recv));
		}
	}else{/* p_who_wanna_recv wants to receive a message from a certain proc: src. */
		p_from		= &proc_table[src];
		if((p_from->flags & SENDING) && (p_from->send_to == proc2pid(p_who_wanna_recv))){
			copyok		= TRUE;
			PROCESS* p	= p_who_wanna_recv->q_sending;

			assert(p);	/* p_from must have been appended to the queue */

			while(p){
				assert(p_from->flags & SENDING);
				if(proc2pid(p) == src){
					p_from = p;
					break;
				}
				prev	= p;
				p	= p->next_sending;	
			}

			assert(p_who_wanna_recv->flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->recv_from == NO_TASK);
			assert(p_who_wanna_recv->send_to == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);

			assert(p_from->flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->recv_from == NO_TASK);
			assert(p_from->send_to == proc2pid(p_who_wanna_recv));
		}
	}
	/*
	 * It's determined from which proc the message will be copied.
	 * Note that this proc must have been waiting for this moment in the queue,
	 * so we should remove it from the queue.
	 */
	if(copyok){
		if(p_from == p_who_wanna_recv->q_sending){	/* the 1st one. */
			assert(prev == 0);
			
			p_who_wanna_recv->q_sending	= p_from->next_sending;
			p_from->next_sending		= 0;
		}else{
			assert(prev);

			prev->next_sending	= p_from->next_sending;
			p_from->next_sending	= 0;
		}

		assert(m);
		assert(p_from->p_msg);
		/* It's time to copy the message. */
		phys_copy(va2la(proc2pid(p_who_wanna_recv), m), va2la(proc2pid(p_from), p_from->p_msg), sizeof(MESSAGE));

		p_from->p_msg		= 0;
		p_from->send_to		= NO_TASK;
		p_from->flags		&= ~SENDING;
		unblock(p_from);
	}
	/*
	 * Unfortunately, nobody is sending any message.
	 * Set flags so that p_who_wanna_recv will not be shceduled util it is unblocked.
	 */
	else{
		p_who_wanna_recv->flags		|= RECEIVING;
		p_who_wanna_recv->p_msg		= m;
		if(src == ANY){
			p_who_wanna_recv->recv_from	= ANY;
		}else{
			p_who_wanna_recv->recv_from	= proc2pid(p_from);
		}

		block(p_who_wanna_recv);

		assert(p_who_wanna_recv->flags == RECEIVING);
		assert(p_who_wanna_recv->p_msg != 0);
		assert(p_who_wanna_recv->recv_from != NO_TASK);
		assert(p_who_wanna_recv->send_to == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);
	}

	return 0;
}
Пример #6
0
PRIVATE int msg_receive(PROCESS *current, int src, MESSAGE *m)
{
    PROCESS *p_who_wanna_recv = current;
    PROCESS *p_from = 0;
    PROCESS *prev = 0;
    int copyok = 0;

    assert(proc2pid(p_who_wanna_recv) != src); // 不能自己接收自己的消息

    if ((p_who_wanna_recv->has_int_msg) &&
            ((src == ANY) || (src == INTERRUPT))) {
        MESSAGE msg;
        reset_msg(&msg);
        msg.source = INTERRUPT;
        msg.type = HARD_INT;
        assert(m);
        phys_copy(va2la(proc2pid(p_who_wanna_recv), m),
                  &msg, sizeof(MESSAGE));

        p_who_wanna_recv->has_int_msg = FALSE;

        assert(p_who_wanna_recv->p_flags == 0);
        assert(p_who_wanna_recv->p_msg == 0);
        assert(p_who_wanna_recv->p_sendto == NO_TASK);
        assert(p_who_wanna_recv->q_sending == 0);

        return 0;
    }

    if (src == ANY) { // 如果要等待来自任何进程的消息
        if (p_who_wanna_recv->q_sending) { // 如果消息队列不为空
            p_from = p_who_wanna_recv->q_sending; // 取消息队列中第一个
            copyok = TRUE;

            assert(p_who_wanna_recv->p_flags == 0);
            assert(p_who_wanna_recv->p_msg == 0);
            assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
            assert(p_who_wanna_recv->p_sendto == NO_TASK);
            assert(p_who_wanna_recv->q_sending != 0);
            assert(p_from->p_flags == SENDING);
            assert(p_from->p_msg != 0);
            assert(p_from->p_recvfrom == NO_TASK);
            assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
        }
    }
    else { // 如果要等待指定进程的消息
        p_from = &proc_table[src];

        if ((p_from->p_flags & SENDING) &&                      // 如果指定的进程正在发送消息
                (p_from->p_sendto == proc2pid(p_who_wanna_recv))) { // 并且就是发送给该进程
            copyok = TRUE;

            PROCESS *p = p_who_wanna_recv->q_sending;
            assert(p);

            /* 在消息队列中找到指定的进程 */
            while (p) {
                assert(p_from->p_flags & SENDING);
                if (proc2pid(p) == src) {
                    p_from = p;
                    break;
                }

                prev = p;
                p = p->next_sending;
            }

            assert(p_who_wanna_recv->p_flags == 0);
            assert(p_who_wanna_recv->p_msg == 0);
            assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
            assert(p_who_wanna_recv->p_sendto == NO_TASK);
            assert(p_who_wanna_recv->q_sending != 0);
            assert(p_from->p_flags == SENDING);
            assert(p_from->p_msg != 0);
            assert(p_from->p_recvfrom == NO_TASK);
            assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
        }
    }

    if (copyok) { // 如果成功接收到了消息
        if (p_from == p_who_wanna_recv->q_sending) {
            assert(prev == 0);
            p_who_wanna_recv->q_sending = p_from->next_sending;
            p_from->next_sending = 0;
        }
        else {
            assert(prev);
            prev->next_sending = p_from->next_sending;
            p_from->next_sending = 0;
        }

        assert(m);
        assert(p_from->p_msg);

        phys_copy(va2la(proc2pid(p_who_wanna_recv), m),
                  va2la(proc2pid(p_from), p_from->p_msg),
                  sizeof(MESSAGE));

        p_from->p_msg = 0;
        p_from->p_sendto = NO_TASK;
        p_from->p_flags &= ~SENDING;
        unblock(p_from); // 恢复发送者
    }
    else {
        p_who_wanna_recv->p_flags |= RECEIVING;
        p_who_wanna_recv->p_msg = m;

        p_who_wanna_recv->p_recvfrom = src == ANY
                                       ? ANY : proc2pid(p_from);

        block(p_who_wanna_recv); // 挂起

        assert(p_who_wanna_recv->p_flags == RECEIVING);
        assert(p_who_wanna_recv->p_msg != 0);
        assert(p_who_wanna_recv->p_recvfrom != NO_TASK);
        assert(p_who_wanna_recv->p_sendto == NO_TASK);
        assert(p_who_wanna_recv->has_int_msg == 0);
    }

    return 0;
}