diff --git a/drivers/at_wini/Makefile b/drivers/at_wini/Makefile index 98cac29a9..25ea6ec7d 100644 --- a/drivers/at_wini/Makefile +++ b/drivers/at_wini/Makefile @@ -14,7 +14,7 @@ MAKE = exec make CC = exec cc CFLAGS = -I$i LDFLAGS = -i -LIBS = -lsys -lsysutil -ltimers +LIBS = -lsysutil -lsys -ltimers OBJ = at_wini.o LIBDRIVER = $d/libdriver/driver.o $d/libdriver/drvlib.o diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index b7499c6b1..2ccf933c3 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -18,6 +18,7 @@ #include #include + #if ENABLE_AT_WINI #define ATAPI_DEBUG 0 /* To debug ATAPI code. */ diff --git a/drivers/libdriver/Makefile b/drivers/libdriver/Makefile index c17be2d65..b1a7c252d 100644 --- a/drivers/libdriver/Makefile +++ b/drivers/libdriver/Makefile @@ -11,7 +11,7 @@ m = $i/minix CC = exec cc CFLAGS = -I$i LDFLAGS = -i -LIBS = -lsys -lsysutil +LIBS = -lsysutil -lsys OBJECTS = driver.o drvlib.o diff --git a/drivers/libdriver/drvlib.c b/drivers/libdriver/drvlib.c index 82b68f6ec..f87396c8e 100644 --- a/drivers/libdriver/drvlib.c +++ b/drivers/libdriver/drvlib.c @@ -8,6 +8,7 @@ #include "drvlib.h" #include + /* Extended partition? */ #define ext_part(s) ((s) == 0x05 || (s) == 0x0F) diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 37894fffc..d13e27861 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -194,6 +194,7 @@ int try; /* Reply to the writer if all output is finished or if an error occured. */ if (tp->tty_outleft == 0 || result != OK) { + /* REVIVE is not possible. I/O on memory mapped consoles finishes. */ tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc, tp->tty_outcum); tp->tty_outcum = 0; diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 90dd7cd3a..2039ab6ee 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -166,7 +166,6 @@ tty_t *tp; int try; { /* Process characters from the circular keyboard buffer. */ - char buf[3]; int scode; unsigned ch; diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 42544c6b5..cdfaf0c44 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -1,3 +1,4 @@ +#define NEW_REVIVE 1 /* This file contains the tesminal driver, both for the IBM console and regular * ASCII terminals. It handles only the device-independent part of a TTY, the * device dependent parts are in console.c, rs232.c, etc. This file contains @@ -26,7 +27,7 @@ * DEV_OPEN: a tty line has been opened * DEV_CLOSE: a tty line has been closed * DEV_SELECT: start select notification request - * DEV_SELECT_CAN: cancel select notification + * DEV_STATUS: FS wants to know status for SELECT or REVIVE * CANCEL: terminate a previous incomplete system call immediately * * m_type TTY_LINE PROC_NR COUNT TTY_SPEK TTY_FLAGS ADDRESS @@ -45,6 +46,8 @@ * |-------------+---------+---------+---------+---------+---------+---------| * | DEV_CLOSE |minor dev| proc nr | | | | | * |-------------+---------+---------+---------+---------+---------+---------| + * | DEV_STATUS | | | | | | | + * |-------------+---------+---------+---------+---------+---------+---------| * | CANCEL |minor dev| proc nr | | | | | * --------------------------------------------------------------------------- * @@ -112,6 +115,7 @@ FORWARD _PROTOTYPE( void do_close, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_write, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr) ); +FORWARD _PROTOTYPE( void do_status, (message *m_ptr) ); FORWARD _PROTOTYPE( void in_transfer, (tty_t *tp) ); FORWARD _PROTOTYPE( int tty_echo, (tty_t *tp, int ch) ); FORWARD _PROTOTYPE( void rawecho, (tty_t *tp, int ch) ); @@ -208,12 +212,10 @@ PUBLIC void main(void) sigset_t sigset = (sigset_t) tty_mess.NOTIFY_ARG; if (sigismember(&sigset, SIGKSTOP)) { cons_stop(); /* switch to primary console */ -#if DEAD_CODE if (irq_hook_id != -1) { sys_irqdisable(&irq_hook_id); sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id); } -#endif } if (sigismember(&sigset, SIGTERM)) cons_stop(); if (sigismember(&sigset, SIGKMESS)) do_new_kmess(&tty_mess); @@ -233,9 +235,14 @@ PUBLIC void main(void) ; /* do nothing; end switch */ } - /* Only device requests should get to this point. - * Check the minor device number. + /* Only device requests should get to this point. All requests, + * except DEV_STATUS, have a minor device number. Check this + * exception and get the minor device number otherwise. */ + if (tty_mess.m_type == DEV_STATUS) { + do_status(&tty_mess); + continue; + } line = tty_mess.TTY_LINE; if ((line - CONS_MINOR) < NR_CONS) { tp = tty_addr(line - CONS_MINOR); @@ -283,6 +290,73 @@ PUBLIC void main(void) } +/*===========================================================================* + * do_status * + *===========================================================================*/ +PRIVATE void do_status(m_ptr) +message *m_ptr; +{ + register struct tty *tp; + int event_found; + int status; + int ops; + + /* Check for select or revive events on any of the ttys. If we found an, + * event return a single status message for it. The FS will make another + * call to see if there is more. + */ + event_found = 0; + for (tp = FIRST_TTY; tp < END_TTY; tp++) { + if ((ops = select_try(tp, tp->tty_select_ops)) && + tp->tty_select_proc == m_ptr->m_source) { + + /* I/O for a selected minor device is ready. */ + m_ptr->m_type = DEV_IO_READY; + m_ptr->DEV_MINOR = tp->tty_index; + m_ptr->DEV_SEL_OPS = ops; + + tp->tty_select_ops &= ~ops; /* unmark select event */ + event_found = 1; + break; + } + else if (tp->tty_inrevived && tp->tty_incaller == m_ptr->m_source) { + + /* Suspended request finished. Send a REVIVE. */ + m_ptr->m_type = DEV_REVIVE; + m_ptr->REP_PROC_NR = tp->tty_inproc; + m_ptr->REP_STATUS = tp->tty_incum; + + tp->tty_inleft = tp->tty_incum = 0; + tp->tty_inrevived = 0; /* unmark revive event */ + event_found = 1; + break; + } + else if (tp->tty_outrevived && tp->tty_outcaller == m_ptr->m_source) { + + /* Suspended request finished. Send a REVIVE. */ + m_ptr->m_type = DEV_REVIVE; + m_ptr->REP_PROC_NR = tp->tty_outproc; + m_ptr->REP_STATUS = tp->tty_outcum; + + tp->tty_outcum = 0; + tp->tty_outrevived = 0; /* unmark revive event */ + event_found = 1; + break; + } + } + + if (! event_found) { + /* No events of interest were found. Return an empty message. */ + m_ptr->m_type = DEV_NO_STATUS; + } + + /* Almost done. Send back the reply message to the caller. */ + if ((status = send(m_ptr->m_source, m_ptr)) != OK) { + panic("TTY","send in do_status failed, status\n", status); + } +} + + /*===========================================================================* * do_read * *===========================================================================*/ @@ -720,7 +794,7 @@ PUBLIC int select_try(struct tty *tp, int ops) { int ready_ops = 0; - /* special case. if line is hung up, no operations will block. + /* Special case. If line is hung up, no operations will block. * (and it can be seen as an exceptional condition.) */ if (tp->tty_termios.c_ospeed == B0) { @@ -758,6 +832,7 @@ PUBLIC int select_try(struct tty *tp, int ops) PUBLIC int select_retry(struct tty *tp) { +#if DEAD_CODE int ops; if((ops = select_try(tp, tp->tty_select_ops))) { message m; @@ -767,6 +842,10 @@ PUBLIC int select_retry(struct tty *tp) notify(tp->tty_select_proc, &m); tp->tty_select_ops &= ~ops; } +#else + if (select_try(tp, tp->tty_select_ops)) + alert(tp->tty_select_proc); +#endif return OK; } @@ -812,9 +891,20 @@ tty_t *tp; /* TTY to check for events. */ /* Reply if enough bytes are available. */ if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) { +#if NEW_REVIVE + if (tp->tty_inrepcode == REVIVE) { + alert(tp->tty_incaller); + tp->tty_inrevived = 1; + } else { + tty_reply(tp->tty_inrepcode, tp->tty_incaller, + tp->tty_inproc, tp->tty_incum); + tp->tty_inleft = tp->tty_incum = 0; + } +#else tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc, tp->tty_incum); tp->tty_inleft = tp->tty_incum = 0; +#endif } } @@ -878,9 +968,20 @@ register tty_t *tp; /* pointer to terminal to read from */ /* Usually reply to the reader, possibly even if incum == 0 (EOF). */ if (tp->tty_inleft == 0) { +#if NEW_REVIVE + if (tp->tty_inrepcode == REVIVE) { + alert(tp->tty_incaller); + tp->tty_inrevived = 1; + } else { + tty_reply(tp->tty_inrepcode, tp->tty_incaller, + tp->tty_inproc, tp->tty_incum); + tp->tty_inleft = tp->tty_incum = 0; + } +#else tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc, tp->tty_incum); tp->tty_inleft = tp->tty_incum = 0; +#endif } } @@ -1369,12 +1470,12 @@ int proc_nr; /* to whom should the reply go? */ int status; /* reply code */ { /* Send a reply to a process that wanted to read or write data. */ - message tty_mess; tty_mess.m_type = code; tty_mess.REP_PROC_NR = proc_nr; tty_mess.REP_STATUS = status; + if ((status = send(replyee, &tty_mess)) != OK) { panic("TTY","tty_reply failed, status\n", status); } diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 436ccdf21..ceb6c68d0 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -46,12 +46,14 @@ typedef struct tty { /* Information about incomplete I/O requests is stored here. */ char tty_inrepcode; /* reply code, TASK_REPLY or REVIVE */ + char tty_inrevived; /* set to 1 if revive callback is pending */ char tty_incaller; /* process that made the call (usually FS) */ char tty_inproc; /* process that wants to read from tty */ vir_bytes tty_in_vir; /* virtual address where data is to go */ int tty_inleft; /* how many chars are still needed */ int tty_incum; /* # chars input so far */ char tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */ + char tty_outrevived; /* set to 1 if revive callback is pending */ char tty_outcaller; /* process that made the call (usually FS) */ char tty_outproc; /* process that wants to write to tty */ vir_bytes tty_out_vir; /* virtual address where data comes from */ @@ -122,6 +124,7 @@ _PROTOTYPE( void tty_wakeup, (clock_t now) ); _PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr, int status) ); _PROTOTYPE( int tty_devnop, (struct tty *tp, int try) ); +_PROTOTYPE( int select_try, (struct tty *tp, int ops) ); _PROTOTYPE( int select_retry, (struct tty *tp) ); /* rs232.c */ diff --git a/include/minix/config.h b/include/minix/config.h index 03e288b88..b6709d723 100755 --- a/include/minix/config.h +++ b/include/minix/config.h @@ -106,7 +106,7 @@ * Directly sending it to TTY only displays the output. Sending it to the * log driver will cause the diagnostics to be buffered and displayed. */ -#define PRINTF_PROC LOG_PROC_NR /* TTY or LOG_PROC_NR */ +#define PRINTF_PROC TTY /* TTY or LOG_PROC_NR */ /* NR_CONS, NR_RS_LINES, and NR_PTYS determine the number of terminals the * system can handle. diff --git a/kernel/clock.c b/kernel/clock.c index d6039e4ac..0e24c1943 100755 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -197,7 +197,7 @@ irq_hook_t *hook; */ if ((next_timeout <= realtime) || (proc_ptr->p_sched_ticks <= 0)) { prev_ptr = proc_ptr; /* store running process */ - lock_alert(HARDWARE, CLOCK); /* send notification */ + lock_notify(HARDWARE, CLOCK); /* send notification */ } return(1); /* reenable interrupts */ } diff --git a/kernel/config.h b/kernel/config.h index 82d27f936..e0aeb0709 100644 --- a/kernel/config.h +++ b/kernel/config.h @@ -58,7 +58,7 @@ /* Buffer to gather randomness. This is used to generate a random stream by * the MEMORY driver when reading from /dev/random. */ -#define RANDOM_ELEMENTS 64 +#define RANDOM_ELEMENTS 32 /* This section contains defines for valuable system resources that are used @@ -70,10 +70,6 @@ #define VDEVIO_BUF_SIZE 64 /* max elements per VDEVIO request */ #define VCOPY_VEC_SIZE 16 /* max elements per VCOPY request */ -#if TEMP_CODE -/* How many buffers for notification messages should there be? */ -#define NR_NOTIFY_BUFS 32 -#endif /* How many bytes for the kernel stack. Space allocated in mpx.s. */ #define K_STACK_BYTES 1024 diff --git a/kernel/glo.h b/kernel/glo.h index 94fb59432..9cde441f0 100755 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -33,12 +33,6 @@ EXTERN char k_reenter; /* kernel reentry count (entry count less 1) */ EXTERN int sched_ticks; /* keep track of quantum usage */ EXTERN unsigned lost_ticks; /* clock ticks counted outside clock task */ -#if TEMP_CODE -/* Declare buffer space and a bit map for notification messages. */ -EXTERN struct notification notify_buffer[NR_NOTIFY_BUFS]; -EXTERN bitchunk_t notify_bitmap[BITMAP_CHUNKS(NR_NOTIFY_BUFS)]; -#endif - #if (CHIP == INTEL) diff --git a/kernel/ipc.h b/kernel/ipc.h index 7569473aa..cd414619e 100644 --- a/kernel/ipc.h +++ b/kernel/ipc.h @@ -17,11 +17,9 @@ #define SEND 1 /* 0 0 0 1 : blocking send */ #define RECEIVE 2 /* 0 0 1 0 : blocking receive */ #define SENDREC 3 /* 0 0 1 1 : SEND + RECEIVE */ -#define ALERT 4 /* 0 1 0 0 : nonblocking notify */ +#define NOTIFY 4 /* 0 1 0 0 : nonblocking notify */ #define ECHO 8 /* 1 0 0 0 : echo a message */ -#define NOTIFY 16 /* 1 0 0 0 0 : temp */ - /* The following bit masks determine what checks that should be done. */ #define CHECK_PTR 0x0B /* 1 0 1 1 : validate message buffer */ #define CHECK_DST 0x05 /* 0 1 0 1 : validate message destination */ diff --git a/kernel/main.c b/kernel/main.c index 054afc937..bdc63580e 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -184,16 +184,12 @@ PRIVATE void announce(void) /*==========================================================================* * prepare_shutdown * *==========================================================================*/ -PUBLIC void prepare_shutdown(tp) -timer_t *tp; +PUBLIC void prepare_shutdown(how) +int how; { -/* This function prepares to shutdown MINIX. It is called by a watchdog - * timer if this is a normal abort so that the sys_abort() call can return - * first. The timer structure passes the shutdown status as an argument. - */ +/* This function prepares to shutdown MINIX. */ register struct proc *rp; static timer_t shutdown_timer; - int how = tmr_arg(tp)->ta_int; message m; /* Show debugging dumps on panics. Make sure that the TTY task is still diff --git a/kernel/proc.c b/kernel/proc.c index 9cbbc424a..ddba8b1fa 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -13,7 +13,7 @@ * lock_sched: a process has run too long; schedule another one * * Changes: - * , 2005 better protection in sys_call() (Jorrit N. Herder) + * Jul 25, 2005 better protection in sys_call() (Jorrit N. Herder) * May 26, 2005 optimized message passing functions (Jorrit N. Herder) * May 24, 2005 new, queued NOTIFY system call (Jorrit N. Herder) * Oct 28, 2004 new, non-blocking SEND and RECEIVE (Jorrit N. Herder) @@ -52,9 +52,7 @@ FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst, message *m_ptr, unsigned flags) ); FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src, message *m_ptr, unsigned flags) ); -FORWARD _PROTOTYPE( int mini_alert, (struct proc *caller_ptr, int dst) ); -FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst, - message *m_ptr ) ); +FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst) ); FORWARD _PROTOTYPE( void ready, (struct proc *rp) ); FORWARD _PROTOTYPE( void unready, (struct proc *rp) ); @@ -62,14 +60,6 @@ FORWARD _PROTOTYPE( void sched, (struct proc *rp) ); FORWARD _PROTOTYPE( void pick_proc, (void) ); -#if TEMP_CODE -#define BuildOldMess(m,n) \ - (m).NOTIFY_SOURCE = (n)->n_source, \ - (m).NOTIFY_TYPE = (n)->n_type, \ - (m).NOTIFY_FLAGS = (n)->n_flags, \ - (m).NOTIFY_ARG = (n)->n_arg; -#endif - #define BuildMess(m_ptr, src, dst_ptr) \ (m_ptr)->m_source = (src); \ (m_ptr)->m_type = NOTIFY_FROM(src); \ @@ -168,7 +158,8 @@ message *m_ptr; /* pointer to message in the caller's space */ */ switch(function) { case SENDREC: - caller_ptr->p_priv->s_flags |= SENDREC_BUSY; + /* A flag is set so that notifications cannot interrupt SENDREC. */ + priv(caller_ptr)->s_flags |= SENDREC_BUSY; /* fall through */ case SEND: result = mini_send(caller_ptr, src_dst, m_ptr, flags); @@ -176,15 +167,12 @@ message *m_ptr; /* pointer to message in the caller's space */ break; /* done, or SEND failed */ } /* fall through for SENDREC */ case RECEIVE: - if(function == RECEIVE) - caller_ptr->p_priv->s_flags &= ~SENDREC_BUSY; + if (function == RECEIVE) + priv(caller_ptr)->s_flags &= ~SENDREC_BUSY; result = mini_receive(caller_ptr, src_dst, m_ptr, flags); break; - case ALERT: - result = mini_alert(caller_ptr, src_dst); - break; case NOTIFY: - result = mini_notify(caller_ptr, src_dst, m_ptr); + result = mini_notify(caller_ptr, src_dst); break; case ECHO: CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, caller_ptr, m_ptr); @@ -278,7 +266,7 @@ unsigned flags; /* system call flags */ if (!(caller_ptr->p_rts_flags & SENDING)) { /* Check if there are pending notifications, except for SENDREC. */ - if (! (caller_ptr->p_priv->s_flags & SENDREC_BUSY)) { + if (! (priv(caller_ptr)->s_flags & SENDREC_BUSY)) { map = &priv(caller_ptr)->s_notify_pending; for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) { @@ -297,34 +285,12 @@ unsigned flags; /* system call flags */ CopyMess(src_proc_nr, proc_addr(HARDWARE), &m, caller_ptr, m_ptr); return(OK); /* report success */ } - -#if TEMP_CODE - ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */ - while (*ntf_q_pp != NULL) { - if (src == ANY || src == (*ntf_q_pp)->n_source) { - /* Found notification. Assemble and copy message. */ - BuildOldMess(m, *ntf_q_pp); - if (m.m_source == HARDWARE) { - m.NOTIFY_ARG = caller_ptr->p_priv->s_int_pending; - caller_ptr->p_priv->s_int_pending = 0; - } - CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m, - caller_ptr, m_ptr); - /* Remove notification from queue and bit map. */ - bit_nr = (int) (*ntf_q_pp - ¬ify_buffer[0]); - *ntf_q_pp = (*ntf_q_pp)->n_next;/* remove from queue */ - free_bit(bit_nr, notify_bitmap, NR_NOTIFY_BUFS); - return(OK); /* report success */ - } - ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */ - } } -#endif /* Check caller queue. Use pointer pointers to keep code simple. */ xpp = &caller_ptr->p_caller_q; while (*xpp != NIL_PROC) { - if (src == ANY || src == proc_nr(*xpp)) { + if (src == ANY || src == proc_nr(*xpp)) { /* Found acceptable message. Copy it and update status. */ CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr); if (((*xpp)->p_rts_flags &= ~SENDING) == 0) ready(*xpp); @@ -333,7 +299,6 @@ unsigned flags; /* system call flags */ } xpp = &(*xpp)->p_q_link; /* proceed to next */ } - } /* No suitable message is available or the caller couldn't send in SENDREC. @@ -352,9 +317,9 @@ unsigned flags; /* system call flags */ /*===========================================================================* - * mini_alert * + * mini_notify * *===========================================================================*/ -PRIVATE int mini_alert(caller_ptr, dst) +PRIVATE int mini_notify(caller_ptr, dst) register struct proc *caller_ptr; /* sender of the notification */ int dst; /* which process to notify */ { @@ -366,7 +331,7 @@ int dst; /* which process to notify */ * can be both sending and receiving during a SENDREC system call. */ if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING && - !(dst_ptr->p_priv->s_flags & SENDREC_BUSY) && + ! (priv(dst_ptr)->s_flags & SENDREC_BUSY) && (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { /* Destination is indeed waiting for a message. Assemble a notification @@ -391,83 +356,10 @@ int dst; /* which process to notify */ } -/*===========================================================================* - * mini_notify * - *===========================================================================*/ -PRIVATE int mini_notify(caller_ptr, dst, m_ptr) -register struct proc *caller_ptr; /* process trying to notify */ -int dst; /* which process to notify */ -message *m_ptr; /* pointer to message buffer */ -{ - register struct proc *dst_ptr = proc_addr(dst); - register struct notification *ntf_p ; - register struct notification **ntf_q_pp; - int ntf_index; - message ntf_mess; - - /* Check to see if target is blocked waiting for this message. A process - * can be both sending and receiving during a SENDREC system call. - */ - if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING && - (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { - - /* Destination is indeed waiting for this message. Check if the source - * is HARDWARE; this is a special case that gets the map of pending - * interrupts as an argument. Then deliver the notification message. - */ - if (proc_nr(caller_ptr) == HARDWARE) { - m_ptr->NOTIFY_ARG = priv(dst_ptr)->s_int_pending; - priv(dst_ptr)->s_int_pending = 0; - } - - CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, dst_ptr, dst_ptr->p_messbuf); - dst_ptr->p_rts_flags &= ~RECEIVING; /* deblock destination */ - if (dst_ptr->p_rts_flags == 0) ready(dst_ptr); - return(OK); - } - - /* Destination is not ready. Add the notification to the pending queue. - * Get pointer to notification message. Don't copy if already in kernel. - */ - if (! iskernelp(caller_ptr)) { - CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, - proc_addr(HARDWARE), &ntf_mess); - m_ptr = &ntf_mess; - } - - /* Enqueue the message. Existing notifications with the same source - * and type are overwritten with newer ones. New notifications that - * are not yet on the list are added to the end. - */ - ntf_q_pp = &dst_ptr->p_ntf_q; - while (*ntf_q_pp != NULL) { - /* Replace notifications with same source and type. */ - if ((*ntf_q_pp)->n_type == m_ptr->NOTIFY_TYPE && - (*ntf_q_pp)->n_source == proc_nr(caller_ptr)) { - (*ntf_q_pp)->n_flags = m_ptr->NOTIFY_FLAGS; - (*ntf_q_pp)->n_arg = m_ptr->NOTIFY_ARG; - return(OK); - } - ntf_q_pp = &(*ntf_q_pp)->n_next; - } - - /* Add to end of queue (found above). Get a free notification buffer. */ - if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0) - return(ENOSPC); - ntf_p = ¬ify_buffer[ntf_index]; /* get pointer to buffer */ - ntf_p->n_source = proc_nr(caller_ptr);/* store notification data */ - ntf_p->n_type = m_ptr->NOTIFY_TYPE; - ntf_p->n_flags = m_ptr->NOTIFY_FLAGS; - ntf_p->n_arg = m_ptr->NOTIFY_ARG; - *ntf_q_pp = ntf_p; /* add to end of queue */ - ntf_p->n_next = NULL; /* mark new end of queue */ - return(OK); -} - /*==========================================================================* * lock_notify * *==========================================================================*/ -PUBLIC int lock_alert(src, dst) +PUBLIC int lock_notify(src, dst) int src; /* sender of the notification */ int dst; /* who is to be notified */ { @@ -481,13 +373,13 @@ int dst; /* who is to be notified */ /* Exception or interrupt occurred, thus already locked. */ if (k_reenter >= 0) { - result = mini_alert(proc_addr(src), dst); + result = mini_notify(proc_addr(src), dst); } /* Call from task level, locking is required. */ else { - lock(0, "alert"); - result = mini_alert(proc_addr(src), dst); + lock(0, "notify"); + result = mini_notify(proc_addr(src), dst); unlock(0); } return(result); diff --git a/kernel/proto.h b/kernel/proto.h index 31b30497f..c70db811c 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -17,17 +17,15 @@ _PROTOTYPE( void reset_timer, (struct timer *tp) ); /* main.c */ _PROTOTYPE( void main, (void) ); -_PROTOTYPE( void prepare_shutdown, (struct timer *tp) ); +_PROTOTYPE( void prepare_shutdown, (int how) ); /* utility.c */ _PROTOTYPE( void kprintf, (const char *fmt, ...) ); _PROTOTYPE( void panic, (_CONST char *s, int n) ); -_PROTOTYPE( int alloc_bit, (bitchunk_t *map, bit_t nr_bits) ); -_PROTOTYPE( void free_bit, (bit_t nr, bitchunk_t *map, bit_t nr_bits) ); /* proc.c */ _PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) ); -_PROTOTYPE( int lock_alert, (int src, int dst) ); +_PROTOTYPE( int lock_notify, (int src, int dst) ); _PROTOTYPE( int lock_send, (int dst, message *m_ptr) ); _PROTOTYPE( void lock_ready, (struct proc *rp) ); _PROTOTYPE( void lock_sched, (struct proc *rp) ); diff --git a/kernel/system.c b/kernel/system.c index 9b933fbaf..bb35eb570 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -201,7 +201,7 @@ int source; * the lowest bytes because the highest bytes won't differ that much. */ int r_next; - unsigned long tsc_high; + unsigned long tsc_high, tsc_low; /* On machines with the RDTSC (cycle counter read instruction - pentium * and up), use that for high-resolution raw entropy gathering. Otherwise, @@ -214,12 +214,15 @@ int source; */ source %= RANDOM_SOURCES; r_next= krandom.bin[source].r_next; - if(machine.processor > 486 && 0) - read_tsc(&tsc_high, &krandom.bin[source].r_buf[r_next]); - else - krandom.bin[source].r_buf[r_next] = read_clock(); - if (krandom.bin[source].r_size < RANDOM_ELEMENTS) + if(machine.processor > 486) { + read_tsc(&tsc_high, &tsc_low); + krandom.bin[source].r_buf[r_next] = tsc_low; + } else { + krandom.bin[source].r_buf[r_next] = read_clock(); + } + if (krandom.bin[source].r_size < RANDOM_ELEMENTS) { krandom.bin[source].r_size ++; + } krandom.bin[source].r_next = (r_next + 1 ) % RANDOM_ELEMENTS; } @@ -247,7 +250,7 @@ irq_hook_t *hook; priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->irq); /* Build notification message and return. */ - lock_alert(HARDWARE, hook->proc_nr); + lock_notify(HARDWARE, hook->proc_nr); return(hook->policy & IRQ_REENABLE); } @@ -267,7 +270,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */ rp = proc_addr(proc_nr); sigaddset(&priv(rp)->s_sig_pending, sig_nr); - lock_alert(SYSTEM, proc_nr); + lock_notify(SYSTEM, proc_nr); } diff --git a/kernel/system/do_abort.c b/kernel/system/do_abort.c index 0676a0ae5..8b2c247b4 100644 --- a/kernel/system/do_abort.c +++ b/kernel/system/do_abort.c @@ -24,7 +24,6 @@ message *m_ptr; /* pointer to request message */ * or ESC after debugging dumps). */ int how = m_ptr->ABRT_HOW; - timer_t *tp; /* See if the monitor is to run the specified instructions. */ if (how == RBT_MONITOR) { @@ -40,13 +39,8 @@ message *m_ptr; /* pointer to request message */ phys_copy(src_phys, kinfo.params_base, (phys_bytes) length); } - /* Set a watchdog timer to shut down, so that this call returns first. - * The timer will expire at the next clock tick, which can be any moment. - * The CLOCK task is only scheduled when the SYSTEM task is done, though. - */ - tp = &priv(proc_addr(KERNEL))->s_alarm_timer; - tmr_arg(tp)->ta_int = how; /* pass status as timer argument */ - set_timer(tp, get_uptime(), prepare_shutdown); + /* Now prepare to shutdown MINIX. */ + prepare_shutdown(how); return(OK); /* pro-forma (really EDISASTER) */ } diff --git a/kernel/system/do_alarm.c b/kernel/system/do_alarm.c index ee2de2d22..a57c00f1e 100644 --- a/kernel/system/do_alarm.c +++ b/kernel/system/do_alarm.c @@ -68,7 +68,7 @@ timer_t *tp; * alarm. The process number is stored in timer argument 'ta_int'. Notify that * process with a notification message from CLOCK. */ - lock_alert(CLOCK, tmr_arg(tp)->ta_int); + lock_notify(CLOCK, tmr_arg(tp)->ta_int); } #endif /* USE_SETALARM */ diff --git a/kernel/type.h b/kernel/type.h index 7edd5c5b0..8bdfebf2c 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -27,19 +27,6 @@ struct memory { phys_clicks size; /* size of memory chunk */ }; -typedef unsigned long notify_mask_t; /* bit mask for notifications */ -typedef short notify_type_t; /* notification type */ -typedef char notify_flags_t; /* notification flags */ -typedef int notify_arg_t; /* notification argument */ - -struct notification { - proc_nr_t n_source; /* sender of notification */ - notify_type_t n_type; /* notification type */ - notify_arg_t n_arg; /* notification argument */ - notify_flags_t n_flags; /* notification flags */ - struct notification* n_next; /* pointer to next notification */ -}; - /* The kernel outputs diagnostic messages in a circular buffer. */ struct kmessages { int km_next; /* next index to write */ @@ -51,7 +38,7 @@ struct randomness { struct { int r_next; /* next index to write */ int r_size; /* number of random elements */ - unsigned long r_buf[RANDOM_ELEMENTS]; /* buffer for random info */ + unsigned short r_buf[RANDOM_ELEMENTS]; /* buffer for random info */ } bin[RANDOM_SOURCES]; }; diff --git a/kernel/utility.c b/kernel/utility.c index 110842601..9f8073623 100755 --- a/kernel/utility.c +++ b/kernel/utility.c @@ -34,7 +34,6 @@ int nr; { /* The system has run aground of a fatal kernel error. Terminate execution. */ static int panicking = 0; - timer_t *tp; if (panicking ++) return; /* prevent recursive panics */ if (mess != NULL) { @@ -43,12 +42,8 @@ int nr; kprintf("\n",NO_NUM); } - /* Make a direct call to shutdown. Interface requires to pass the shutdown - * status by means of a timer. - */ - tp = &priv(proc_addr(KERNEL))->s_alarm_timer; - tmr_arg(tp)->ta_int = RBT_PANIC; - prepare_shutdown(tp); + /* Abort MINIX. */ + prepare_shutdown(RBT_PANIC); } @@ -148,57 +143,3 @@ int c; /* character to append */ } - -#if TEMP_CODE - -/*===========================================================================* - * free_bit * - *===========================================================================*/ -PUBLIC void free_bit(bit_nr, bitmap, nr_bits) -bit_t bit_nr; -bitchunk_t *bitmap; -bit_t nr_bits; -{ - bitchunk_t *chunk; - if (bit_nr >= nr_bits) { - kprintf("Warning, free_bit: %d illegal index\n", bit_nr); - return; - } - chunk = &bitmap[(bit_nr/BITCHUNK_BITS)]; - *chunk &= ~(1 << (bit_nr % BITCHUNK_BITS)); -} - -/*===========================================================================* - * alloc_bit * - *===========================================================================*/ -PUBLIC int alloc_bit(bitmap, nr_bits) -bitchunk_t *bitmap; -bit_t nr_bits; -{ - bitchunk_t *chunk; - int nr_chunks; - int bit_nr; - int i; - - /* Iterate over the words in block. */ - nr_chunks = BITMAP_CHUNKS(nr_bits); - for (chunk = &bitmap[0]; chunk < &bitmap[nr_chunks]; chunk++) { - - /* Does this chunk contain a free bit? */ - if (*chunk == (bitchunk_t) ~0) continue; - - /* Get bit number from the start of the bit map. */ - for (i = 0; (*chunk & (1 << i)) != 0; ++i) {} - bit_nr = (chunk - &bitmap[0]) * BITCHUNK_BITS + i; - - /* Don't allocate bits beyond the end of the map. */ - if (bit_nr >= nr_bits) break; - - *chunk |= 1 << bit_nr % BITCHUNK_BITS; - return(bit_nr); - - } - return(-1); -} - -#endif diff --git a/lib/i386/rts/_ipc.s b/lib/i386/rts/_ipc.s index 7eec5b08c..a1993f47a 100755 --- a/lib/i386/rts/_ipc.s +++ b/lib/i386/rts/_ipc.s @@ -4,7 +4,7 @@ ! See src/kernel/ipc.h for C definitions SEND = 1 RECEIVE = 2 -SENDREC = 3 + 32 ! flags 0x20 to request fresh answer +SENDREC = 3 NOTIFY = 16 ALERT = 4 ECHO = 8 diff --git a/lib/sysutil/kputc.c b/lib/sysutil/kputc.c index 708579819..5d3918fd2 100644 --- a/lib/sysutil/kputc.c +++ b/lib/sysutil/kputc.c @@ -1,8 +1,6 @@ /* A server must occasionally print some message. It uses a simple version of * printf() found in the system lib that calls kputc() to output characters. * Printing is done with a call to the kernel, and not by going through FS. - * This way system messages end up in the kernel messages buffer and can be - * reviewed at a later time. * * This routine can only be used by servers and device drivers. The kernel * must define its own kputc(). Note that the log driver also defines its own @@ -24,21 +22,23 @@ int c; message m; if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) { - /* Send the buffer to the system task, or, if this process is not a - * server yet, to standard error. - */ + + /* Send the buffer to the PRINTF_PROC driver. */ m.DIAG_BUF_COUNT = buf_count; m.DIAG_PRINT_BUF = print_buf; m.DIAG_PROC_NR = SELF; m.m_type = DIAGNOSTICS; - if (_sendrec(PRINTF_PROC, &m) != 0) { - m.m1_i1 = 2; - m.m1_i2 = buf_count; - m.m1_p1 = print_buf; - m.m_type = WRITE; - (void) _sendrec(FS, &m); - } + (void) _sendrec(PRINTF_PROC, &m); buf_count = 0; + + /* If the output fails, e.g., due to an ELOCKED, do not retry output + * at the FS as if this were a normal user-land printf(). This may + * result in even worse problems. + */ + } + if (c != 0) { + + /* Append a single character to the output buffer. */ + print_buf[buf_count++] = c; } - if (c != 0) print_buf[buf_count++] = c; }