Exemplo n.º 1
0
void
do_apic_timer(struct pt_regs *regs, unsigned int vector)
{
	expire_timers();

#ifdef CONFIG_TASK_MEAS
	arch_task_meas();
#endif

	// This causes schedule() to be called right before
	// the next return to user-space
	set_bit(TF_NEED_RESCHED_BIT, &current->arch.flags);
}
Exemplo n.º 2
0
/*===========================================================================*
 *			       do_control_msgs				     *
 *===========================================================================*/
static void *do_control_msgs(void *arg)
{
  struct job my_job;

  my_job = *((struct job *) arg);
  fp = my_job.j_fp;

  /* Check for special control messages. */
  if (job_m_in.m_source == CLOCK) {
	/* Alarm timer expired. Used only for select(). Check it. */
	expire_timers(job_m_in.NOTIFY_TIMESTAMP);
  }

  thread_cleanup(NULL);
  return(NULL);
}
Exemplo n.º 3
0
int main(__unused int argc, __unused char ** argv)
{
	sef_local_startup();

	for(;;) {
		int err, ipc_status;
		message m;

		netif_poll_lo();

		mq_process();

		if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) {
			printf("LWIP : sef_receive_status errr %d\n", err);
			continue;
		}

		if (m.m_source == VFS_PROC_NR)
			socket_request(&m, ipc_status);
		else if (is_ipc_notify(ipc_status)) {
			switch (m.m_source) {
			case CLOCK:
				expire_timers(m.m_notify.timestamp);
				break;
			case DS_PROC_NR:
				ds_event();
				break;
			case PM_PROC_NR:
				panic("LWIP : unhandled event from PM");
				break;
			default:
				printf("LWIP : unexpected notify from %d\n",
								m.m_source);
				continue;
			}
		} else
			/* all other request can be from drivers only */
			driver_request(&m);
	}

	return 0;
}
Exemplo n.º 4
0
void poll_loop(void)
{
    SIG_ENTITY *sig;
    fd_set perm,set;
    int fds,ret;

    FD_ZERO(&perm);
    FD_SET(kernel,&perm);
    fds = kernel+1;
    for (sig = entities; sig; sig = sig->next) {
	FD_SET(sig->signaling,&perm);
	if (fds <= sig->signaling) fds = sig->signaling+1;
    }
    gettimeofday(&now,NULL);
    while (!stop) {
	set = perm;
	poll_signals();
	/*
	 * Here we have a small race condition: if a signal is delivered after
	 * poll_signals tests for it but before select sleeps, we miss that
	 * signal. If it is sent again, we're of course likely to get it. This
	 * isn't worth fixing, because those signals are only used for
	 * debugging anyway.
	 */
	ret = select(fds,&set,NULL,NULL,next_timer());
	if (ret < 0) {
	    if (errno != EINTR) perror("select");
	}
	else {
	    diag(COMPONENT,DIAG_DEBUG,"----------");
	    gettimeofday(&now,NULL);
	    if (FD_ISSET(kernel,&set)) recv_kernel();
	    for (sig = entities; sig; sig = sig->next)
		if (FD_ISSET(sig->signaling,&set)) recv_signaling(sig);
	    expire_timers();
	      /* expire timers after handling messges to make sure we don't
		 time out unnecessarily because of scheduling delays */
	}
    }
}
Exemplo n.º 5
0
Arquivo: main.c Projeto: Sciumo/minix
/*===========================================================================*
 *			       do_control_msgs				     *
 *===========================================================================*/
static void *do_control_msgs(void *arg)
{
  struct job my_job;

  my_job = *((struct job *) arg);
  fp = my_job.j_fp;

  /* Check for special control messages. */
  if (job_m_in.m_source == CLOCK) {
	/* Alarm timer expired. Used only for select(). Check it. */
	expire_timers(job_m_in.NOTIFY_TIMESTAMP);
  } else if (job_m_in.m_source == DS_PROC_NR) {
	/* DS notifies us of an event. */
	ds_event();
  } else {
	/* Device notifies us of an event. */
	dev_status(&job_m_in);
  }

  thread_cleanup(NULL);
  return(NULL);
}
Exemplo n.º 6
0
Arquivo: tty.c Projeto: Hooman3/minix
/*===========================================================================*
 *				tty_task				     *
 *===========================================================================*/
int main(void)
{
/* Main routine of the terminal task. */

  message tty_mess;		/* buffer for all incoming messages */
  int ipc_status;
  int line;
  int r;
  register tty_t *tp;

  /* SEF local startup. */
  sef_local_startup();
  while (TRUE) {
	/* Check for and handle any events on any of the ttys. */
	for (tp = FIRST_TTY; tp < END_TTY; tp++) {
		if (tp->tty_events) handle_events(tp);
	}

	/* Get a request message. */
	r= driver_receive(ANY, &tty_mess, &ipc_status);
	if (r != 0)
		panic("driver_receive failed with: %d", r);

	/* First handle all kernel notification types that the TTY supports. 
	 *  - An alarm went off, expire all timers and handle the events. 
	 *  - A hardware interrupt also is an invitation to check for events. 
	 *  - A new kernel message is available for printing.
	 *  - Reset the console on system shutdown. 
	 * Then see if this message is different from a normal device driver
	 * request and should be handled separately. These extra functions
	 * do not operate on a device, in constrast to the driver requests. 
	 */

	if (is_ipc_notify(ipc_status)) {
		switch (_ENDPOINT_P(tty_mess.m_source)) {
			case CLOCK:
				/* run watchdogs of expired timers */
				expire_timers(tty_mess.m_notify.timestamp);
				break;
			case HARDWARE: 
				/* hardware interrupt notification */

#if NR_RS_LINES > 0
				/* serial I/O */
				if (tty_mess.m_notify.interrupts & rs_irq_set)
					rs_interrupt(&tty_mess);
#endif
				/* run watchdogs of expired timers */
				expire_timers(tty_mess.m_notify.timestamp);
				break;
			default:
				/* do nothing */
				break;
		}

		/* done, get new message */
		continue;
	}

	switch (tty_mess.m_type) { 
	case TTY_FKEY_CONTROL:		/* (un)register a fkey observer */
		do_fkey_ctl(&tty_mess);
		continue;
	case TTY_INPUT_UP:
	case TTY_INPUT_EVENT:
		do_input(&tty_mess);
		continue;
	default:			/* should be a driver request */
		;			/* do nothing; end switch */
	}

	if (!IS_CDEV_RQ(tty_mess.m_type)) {
		chardriver_process(&tty_tab, &tty_mess, ipc_status);
		continue;
	}

	/* Only device requests should get to this point.
	 * All requests have a minor device number.
	 */
	if (OK != chardriver_get_minor(&tty_mess, &line))
		continue;

	if (line == VIDEO_MINOR) {
		do_video(&tty_mess, ipc_status);
		continue;
	}

	/* Execute the requested device driver function. */
	chardriver_process(&tty_tab, &tty_mess, ipc_status);
  }

  return 0;
}
Exemplo n.º 7
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main(void)
{
	/* Main routine of the scheduler. */
	message m_in;	/* the incoming message itself is kept here. */
	int call_nr;	/* system call number */
	int who_e;	/* caller's endpoint */
	int result;	/* result to system call */
	int rv;

	/* SEF local startup. */
	sef_local_startup();

	/* Initialize scheduling timers, used for running balance_queues */
	init_scheduling();

	/* my Hello code*/
	printf("\n%s\n", "    =========================================================");
	printf("%s\n", "        Hello, Minix is now using a lottery scheduler.");
	printf("%s\n\n", "    =========================================================");

	/* This is SCHED's main loop - get work and do it, forever and forever. */
	while (TRUE) {
		int ipc_status;

		/* Wait for the next message and extract useful information from it. */
		if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
			panic("SCHED sef_receive error");
		who_e = m_in.m_source;	/* who sent the message */
		call_nr = m_in.m_type;	/* system call number */

		/* Check for system notifications first. Special cases. */
		if (is_ipc_notify(ipc_status)) {
			switch(who_e) {
				case CLOCK:
					expire_timers(m_in.NOTIFY_TIMESTAMP);
					continue;	/* don't reply */
				default :
					result = ENOSYS;
			}

			goto sendreply;
		}

		switch(call_nr) {
		case SCHEDULING_INHERIT:
		case SCHEDULING_START:
			result = do_start_scheduling(&m_in);
			break;
		case SCHEDULING_STOP:
			result = do_stop_scheduling(&m_in);
			break;
		case SCHEDULING_SET_NICE:
			result = do_nice(&m_in);
			break;
		case SCHEDULING_NO_QUANTUM:
			/* This message was sent from the kernel, don't reply */
			if (IPC_STATUS_FLAGS_TEST(ipc_status,
				IPC_FLG_MSG_FROM_KERNEL)) {
				if ((rv = do_noquantum(&m_in)) != (OK)) {
					printf("SCHED: Warning, do_noquantum "
						"failed with %d\n", rv);
				}
				continue; /* Don't reply */
			}
			else {
				printf("SCHED: process %d faked "
					"SCHEDULING_NO_QUANTUM message!\n",
						who_e);
				result = EPERM;
			}
			break;
		default:
			result = no_sys(who_e, call_nr);
		}

sendreply:
		/* Send reply. */
		if (result != SUSPEND) {
			m_in.m_type = result;  		/* build reply message */
			reply(who_e, &m_in);		/* send it away */
		}
 	}

	return(OK);
}
Exemplo n.º 8
0
Arquivo: main.c Projeto: bend/Minix-RC
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main(void)
{
/* This is the main program of the file system.  The main loop consists of
 * three major activities: getting new work, processing the work, and sending
 * the reply.  This loop never terminates as long as the file system runs.
 */
  int error;

  /* SEF local startup. */
  sef_local_startup();

  /* This is the main loop that gets work, processes it, and sends replies. */
  while (TRUE) {
	SANITYCHECK;
	get_work();		/* sets who and call_nr */

	if (call_nr == DEV_REVIVE)
	{
		endpoint_t endpt;

		endpt = m_in.REP_ENDPT;
		if(endpt == VFS_PROC_NR) {
			endpt = suspended_ep(m_in.m_source, m_in.REP_IO_GRANT);
			if(endpt == NONE) {
				printf("FS: proc with "
			"grant %d from %d not found (revive)\n",
					m_in.REP_IO_GRANT, m_in.m_source);
				continue;
			}
		}
		revive(endpt, m_in.REP_STATUS);
		continue;
	}
	if (call_nr == DEV_REOPEN_REPL)
	{
		reopen_reply();
		continue;
	}
	if (call_nr == DEV_CLOSE_REPL)
	{
		close_reply();
		continue;
	}
	if (call_nr == DEV_SEL_REPL1)
	{
		select_reply1();
		continue;
	}
	if (call_nr == DEV_SEL_REPL2)
	{
		select_reply2();
		continue;
	}

 	/* Check for special control messages first. */
        if (is_notify(call_nr)) {
		if (who_e == CLOCK)
		{
			/* Alarm timer expired. Used only for select().
			 * Check it.
			 */
			expire_timers(m_in.NOTIFY_TIMESTAMP);
		}
		else if(who_e == DS_PROC_NR)
		{
			/* DS notifies us of an event. */
			ds_event();
		}
		else
		{
			/* Device notifies us of an event. */
			dev_status(&m_in);
		}
		SANITYCHECK;
		continue;
	}

	/* We only expect notify()s from tasks. */
	if(who_p < 0) {
    		printf("FS: ignoring message from %d (%d)\n",
			who_e, m_in.m_type);
		continue;
	}

	/* Now it's safe to set and check fp. */
	fp = &fproc[who_p];	/* pointer to proc table struct */
	super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);   /* su? */

#if DO_SANITYCHECKS
	if(fp_is_blocked(fp)) {
		printf("VFS: requester %d call %d: suspended\n",
			who_e, call_nr);
		panic("requester suspended");
	}
#endif

	/* Calls from PM. */
	if (who_e == PM_PROC_NR) {
		service_pm();

		continue;
	}

		SANITYCHECK;

	  /* Other calls. */
	  switch(call_nr)
	  {
	      case MAPDRIVER:
		error= do_mapdriver();
		if (error != SUSPEND) reply(who_e, error);
		break;

	      default:
		/* Call the internal function that does the work. */
		if (call_nr < 0 || call_nr >= NCALLS) { 
			error = SUSPEND;
			/* Not supposed to happen. */
			printf("VFS: illegal %d system call by %d\n",
				call_nr, who_e);
		} else if (fp->fp_pid == PID_FREE) {
			error = ENOSYS;
			printf(
		"FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n",
				 who_e, call_nr, m_in.endpt1);
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif
			SANITYCHECK;
			error = (*call_vec[call_nr])();
			SANITYCHECK;
		}

		/* Copy the results back to the user and send reply. */
		if (error != SUSPEND) { reply(who_e, error); }
	}
	SANITYCHECK;
  }
  return(OK);				/* shouldn't come here */
}
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main()
{
/* Main routine of the process manager. */
  int result;

  /* SEF local startup. */
  sef_local_startup();
  
  
// Initialization of the semarray (of pointers) to NULL
  
  register struct mproc *rmp;
  
// rmp is the pointer to the struct of the process table

    	 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
    	 
    	 {
    				 for(int i=0; i<12; i++) // for all 12 semaphores
    				  {
    					  rmp->semarray[i]=NULL;
    				  }
    				  
    	  }

  // end of Initialization
  

/* This is PM's main loop-  get work and do it, forever and forever. */
  
while (TRUE) {
	  int ipc_status;

	  /* Wait for the next message and extract useful information from it. */
	  if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
		  panic("PM sef_receive_status error");
	  who_e = m_in.m_source;	/* who sent the message */
	  if(pm_isokendpt(who_e, &who_p) != OK)
		  panic("PM got message from invalid endpoint: %d", who_e);
	  call_nr = m_in.m_type;	/* system call number */

	  /* Process slot of caller. Misuse PM's own process slot if the kernel is
	   * calling. This can happen in case of synchronous alarms (CLOCK) or or
	   * event like pending kernel signals (SYSTEM).
	   */
	  mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
	  if(who_p >= 0 && mp->mp_endpoint != who_e) {
		  panic("PM endpoint number out of sync with source: %d",
				  			mp->mp_endpoint);
	  }

	/* Drop delayed calls from exiting processes. */
	if (mp->mp_flags & EXITING)
		continue;

	/* Check for system notifications first. Special cases. */
	if (is_ipc_notify(ipc_status)) {
		if (who_p == CLOCK) {
			expire_timers(m_in.NOTIFY_TIMESTAMP);
		}

		/* done, send reply and continue */
		sendreply();
		continue;
	}

	switch(call_nr)
	{
	case PM_SETUID_REPLY:
	case PM_SETGID_REPLY:
	case PM_SETSID_REPLY:
	case PM_EXEC_REPLY:
	case PM_EXIT_REPLY:
	case PM_CORE_REPLY:
	case PM_FORK_REPLY:
	case PM_SRV_FORK_REPLY:
	case PM_UNPAUSE_REPLY:
	case PM_REBOOT_REPLY:
	case PM_SETGROUPS_REPLY:
		if (who_e == VFS_PROC_NR)
		{
			handle_vfs_reply();
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case COMMON_GETSYSINFO:
		result = do_getsysinfo();
		break;
	default:
		/* Else, if the system call number is valid, perform the
		 * call.
		 */
		if ((unsigned) call_nr >= NCALLS) {
			result = ENOSYS;
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif

			result = (*call_vec[call_nr])();

		}
		break;
	}

	/* Send reply. */
	if (result != SUSPEND) setreply(who_p, result);
	sendreply();
  }
  return(OK);
}
Exemplo n.º 10
0
Arquivo: io.c Projeto: ebichu/dd-wrt
void poll_loop(void)
{
    ITF *itf,*next_itf;
    ENTRY *entry,*next_entry;
    VCC *vcc,*next_vcc;
    int fds,ret;

    gettimeofday(&now,NULL);
    while (1) {
	FD_ZERO(&rset);
	FD_ZERO(&cset);
	FD_SET(kernel,&rset);
	FD_SET(unix_sock,&rset);
	if (incoming >= 0) FD_SET(incoming,&rset);
	fds = incoming+1;
	if (kernel >= fds) fds = kernel+1;
	if (unix_sock >= fds) fds = unix_sock+1;
	for (itf = itfs; itf; itf = itf->next)
	    for (entry = itf->table; entry; entry = entry->next)
		for (vcc = entry->vccs; vcc; vcc = vcc->next) {
		    if (vcc->connecting) FD_SET(vcc->fd,&cset);
		    else FD_SET(vcc->fd,&rset);
		    if (vcc->fd >= fds) fds = vcc->fd+1;
		}
	for (entry = unknown_incoming; entry; entry = entry->next) {
	    if (!entry->vccs || entry->vccs->next) {
		diag(COMPONENT,DIAG_ERROR,"internal error: bad unknown entry");
		continue;
	    }
	    FD_SET(entry->vccs->fd,&rset);
	    if (entry->vccs->fd >= fds) fds = entry->vccs->fd+1;
	}
	for (vcc = unidirectional_vccs; vcc; vcc = vcc->next) {
	    FD_SET(vcc->fd,&rset);
	    if (vcc->fd >= fds) fds = vcc->fd+1;
	}
	ret = select(fds,&rset,&cset,NULL,next_timer());
/*
 * Now here's something strange: < 0.32 needed the exception mask to be NULL
 * in order to work, due to a bug in atm_select. In 0.32, this has been fixed.
 * Also, 2.1 kernels use the poll mechanism and not select, so select is
 * emulated on top of poll. Now the funny bit is that, as soon as the exception
 * set is non-NULL, when a non-blocking connect finishes, select returns one
 * but has none if the possible bits set in either rset or cset. To make things
 * even stranger, no exception is actually found in sys_select, so this must be
 * some very odd side-effect ... The work-around for now is to simply pass NULL
 * for the exception mask (which is the right thing to do anyway, but it'd be
 * nice if doing a perfectly valid variation wouldn't blow up the system ...)
 */
#if 0
{
  int i;
  for (i = 0; i < sizeof(rset); i++)
   fprintf(stderr,"%02x:%02x ",((unsigned char *) &rset)[i],
    ((unsigned char *) &cset)[i]);
  fprintf(stderr,"\n");
}
#endif
	if (ret < 0) {
	    if (errno != EINTR) perror("select");
	}
	else {
	    diag(COMPONENT,DIAG_DEBUG,"----------");
	    gettimeofday(&now,NULL);
	    if (FD_ISSET(kernel,&rset)) recv_kernel();
	    if (FD_ISSET(unix_sock,&rset)) recv_unix();
	    if (incoming >= 0 && FD_ISSET(incoming,&rset)) accept_new();
	    for (itf = itfs; itf; itf = next_itf) {
		next_itf = itf->next;
		for (entry = itf->table; entry; entry = next_entry) {
		    next_entry = entry->next;
		    for (vcc = entry->vccs; vcc; vcc = next_vcc) {
			next_vcc = vcc->next;
			if (FD_ISSET(vcc->fd,&rset)) recv_vcc(vcc);
			else if (FD_ISSET(vcc->fd,&cset))
				complete_connect(vcc);
		    }
		}
	    }
	    for (entry = unknown_incoming; entry; entry = next_entry) {
		next_entry = entry->next;
		if (FD_ISSET(entry->vccs->fd,&rset)) recv_vcc(entry->vccs);
	    }
	    for (vcc = unidirectional_vccs; vcc; vcc = next_vcc) {
		next_vcc = vcc->next;
		if (FD_ISSET(vcc->fd,&rset)) drain_vcc(vcc);
	    }
	    expire_timers();
	      /* expire timers after handling messages to make sure we don't
		 time out unnecessarily because of scheduling delays */
	}
	table_changed();
    }
}
Exemplo n.º 11
0
Arquivo: main.c Projeto: wmdwjwm/minix
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main()
{
/* Main routine of the process manager. */
  unsigned int call_index;
  int ipc_status, result;

  /* SEF local startup. */
  sef_local_startup();

  /* This is PM's main loop-  get work and do it, forever and forever. */
  while (TRUE) {
	/* Wait for the next message. */
	if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
		panic("PM sef_receive_status error");

	/* Check for system notifications first. Special cases. */
	if (is_ipc_notify(ipc_status)) {
		if (_ENDPOINT_P(m_in.m_source) == CLOCK)
			expire_timers(m_in.m_notify.timestamp);

		/* done, continue */
		continue;
	}

	/* Extract useful information from the message. */
	who_e = m_in.m_source;	/* who sent the message */
	if (pm_isokendpt(who_e, &who_p) != OK)
		panic("PM got message from invalid endpoint: %d", who_e);
	mp = &mproc[who_p];	/* process slot of caller */
	call_nr = m_in.m_type;	/* system call number */

	/* Drop delayed calls from exiting processes. */
	if (mp->mp_flags & EXITING)
		continue;

	if (IS_VFS_PM_RS(call_nr) && who_e == VFS_PROC_NR) {
		handle_vfs_reply();

		result = SUSPEND;		/* don't reply */
	} else if (call_nr == PROC_EVENT_REPLY) {
		result = do_proc_event_reply();
	} else if (IS_PM_CALL(call_nr)) {
		/* If the system call number is valid, perform the call. */
		call_index = (unsigned int) (call_nr - PM_BASE);

		if (call_index < NR_PM_CALLS && call_vec[call_index] != NULL) {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_index]++;
#endif

			result = (*call_vec[call_index])();
		} else
			result = ENOSYS;
	} else
		result = ENOSYS;

	/* Send reply. */
	if (result != SUSPEND) reply(who_p, result);
  }
  return(OK);
}
Exemplo n.º 12
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main(void)
{
/* This is the main program of the file system.  The main loop consists of
 * three major activities: getting new work, processing the work, and sending
 * the reply.  This loop never terminates as long as the file system runs.
 */
  int transid;
  struct worker_thread *wp;

  /* SEF local startup. */
  sef_local_startup();

  printf("Started VFS: %d worker thread(s)\n", NR_WTHREADS);

  /* This is the main loop that gets work, processes it, and sends replies. */
  while (TRUE) {
	worker_yield();	/* let other threads run */

	send_work();

	/* The get_work() function returns TRUE if we have a new message to
	 * process. It returns FALSE if it spawned other thread activities.
	 */
	if (!get_work())
		continue;

	transid = TRNS_GET_ID(m_in.m_type);
	if (IS_VFS_FS_TRANSID(transid)) {
		wp = worker_get((thread_t) transid - VFS_TRANSID);
		if (wp == NULL || wp->w_fp == NULL) {
			printf("VFS: spurious message %d from endpoint %d\n",
				m_in.m_type, m_in.m_source);
			continue;
		}
		m_in.m_type = TRNS_DEL_ID(m_in.m_type);
		do_reply(wp);
		continue;
	} else if (who_e == PM_PROC_NR) { /* Calls from PM */
		/* Special control messages from PM */
		service_pm();
		continue;
	} else if (is_notify(call_nr)) {
		/* A task ipc_notify()ed us */
		switch (who_e) {
		case DS_PROC_NR:
			/* Start a thread to handle DS events, if no thread
			 * is pending or active for it already. DS is not
			 * supposed to issue calls to VFS or be the subject of
			 * postponed PM requests, so this should be no problem.
			 */
			if (worker_can_start(fp))
				handle_work(ds_event);
			break;
		case KERNEL:
			mthread_stacktraces();
			break;
		case CLOCK:
			/* Timer expired. Used only for select(). Check it. */
			expire_timers(m_in.m_notify.timestamp);
			break;
		default:
			printf("VFS: ignoring notification from %d\n", who_e);
		}
		continue;
	} else if (who_p < 0) { /* i.e., message comes from a task */
		/* We're going to ignore this message. Tasks should
		 * send ipc_notify()s only.
		 */
		 printf("VFS: ignoring message from %d (%d)\n", who_e, call_nr);
		 continue;
	}

	if (IS_BDEV_RS(call_nr)) {
		/* We've got results for a block device request. */
		bdev_reply();
	} else if (IS_CDEV_RS(call_nr)) {
		/* We've got results for a character device request. */
		cdev_reply();
	} else {
		/* Normal syscall. This spawns a new thread. */
		handle_work(do_work);
	}
  }
  return(OK);				/* shouldn't come here */
}
Exemplo n.º 13
0
/*===========================================================================*
 *				tty_task				     *
 *===========================================================================*/
int main(int argc, char **argv)
{
/* Main routine of the terminal task. */

  message tty_mess;		/* buffer for all incoming messages */
  int ipc_status;
  int line;
  int r;
  register tty_t *tp;

  env_setargs(argc, argv);

  tty_startup();

  while (TRUE) {
	/* Check for and handle any events on any of the ttys. */
	for (tp = FIRST_TTY; tp < END_TTY; tp++) {
		if (tp->tty_events) handle_events(tp);
	}

	/* Get a request message. */
	r= driver_receive(ANY, &tty_mess, &ipc_status);
	if (r != 0)
		panic("driver_receive failed with: %d", r);

	if (is_ipc_notify(ipc_status)) {
		switch (_ENDPOINT_P(tty_mess.m_source)) {
			case CLOCK:
				/* run watchdogs of expired timers */
				expire_timers(tty_mess.m_notify.timestamp);
				break;
			default:
				/* do nothing */
				break;
		}

		/* done, get new message */
		continue;
	}

	if (!IS_CDEV_RQ(tty_mess.m_type)) {
		chardriver_process(&tty_tab, &tty_mess, ipc_status);
		continue;
	}

	/* Only device requests should get to this point.
	 * All requests have a minor device number.
	 */
	if (OK != chardriver_get_minor(&tty_mess, &line))
		continue;

	if (is_pty(line)) {
		/* Terminals and pseudo terminals belong together. We can only
		 * make a distinction between the two based on minor number and
		 * not on position in the tty_table. Hence this special case.
		 */
		do_pty(&tty_mess, ipc_status);
		continue;
	}

	/* Execute the requested device driver function. */
	chardriver_process(&tty_tab, &tty_mess, ipc_status);
  }

  return 0;
}