Fixed some comments and reorganized some code.
Fixed minor bug in notify() function.
This commit is contained in:
parent
821dfb06ed
commit
614f49b557
|
@ -22,7 +22,6 @@ HEAD = mpx.o
|
|||
|
||||
OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \
|
||||
i8259.o exception.o system.o clock.o misc.o \
|
||||
dummy.o
|
||||
|
||||
SYS = system/system.a
|
||||
|
||||
|
@ -135,8 +134,6 @@ table.o: proc.h
|
|||
table.o: sendmask.h
|
||||
table.o: $b/int86.h
|
||||
|
||||
dummy.o: $a
|
||||
|
||||
system/system.a: $a $h/devio.h $h/com.h
|
||||
system/system.a: proc.h protect.h system.h sendmask.h
|
||||
system/system.a: $s/ptrace.h $s/sigcontext.h
|
||||
|
|
|
@ -42,6 +42,7 @@ FORWARD _PROTOTYPE( void init_clock, (void) );
|
|||
FORWARD _PROTOTYPE( int clock_handler, (irq_hook_t *hook) );
|
||||
FORWARD _PROTOTYPE( int do_clocktick, (message *m_ptr) );
|
||||
|
||||
|
||||
/* Constant definitions. */
|
||||
#define SCHED_RATE (MILLISEC*HZ/1000) /* number of ticks per schedule */
|
||||
#define MILLISEC 100 /* how often to call the scheduler */
|
||||
|
@ -80,7 +81,8 @@ PRIVATE clock_t next_timeout; /* realtime that next timer expires */
|
|||
*/
|
||||
PRIVATE clock_t realtime; /* real time clock */
|
||||
|
||||
/* Variables changed by interrupt handler. */
|
||||
/* Variables for and changed by the CLOCK's interrupt handler. */
|
||||
PRIVATE irq_hook_t clock_hook;
|
||||
PRIVATE clock_t pending_ticks; /* ticks seen by low level only */
|
||||
PRIVATE int sched_ticks = SCHED_RATE; /* counter: when 0, call scheduler */
|
||||
PRIVATE struct proc *prev_ptr; /* last user process run by clock */
|
||||
|
@ -120,10 +122,13 @@ PUBLIC void clock_task()
|
|||
result = EBADREQUEST;
|
||||
}
|
||||
|
||||
/* Send reply, unless inhibited, e.g. by do_clocktick(). */
|
||||
/* Send reply, unless inhibited, e.g. by do_clocktick(). Use the kernel
|
||||
* function lock_send() to prevent a system call trap. The destination
|
||||
* is known to be blocked waiting for a message.
|
||||
*/
|
||||
if (result != EDONTREPLY) {
|
||||
m.m_type = result;
|
||||
send(m.m_source, &m);
|
||||
lock_send(proc_addr(CLOCK), m.m_source, &m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +143,6 @@ message *m_ptr; /* pointer to request message */
|
|||
/* Despite its name, this routine is not called on every clock tick. It
|
||||
* is called on those clock ticks when a lot of work needs to be done.
|
||||
*/
|
||||
|
||||
register struct proc *rp;
|
||||
register int proc_nr;
|
||||
timer_t *tp;
|
||||
|
@ -216,7 +220,6 @@ irq_hook_t *hook;
|
|||
* faster on a 5MHz 8088, and make task debugging much easier since there are
|
||||
* no task switches on an inactive system.
|
||||
*/
|
||||
|
||||
register struct proc *rp;
|
||||
register unsigned ticks;
|
||||
clock_t now;
|
||||
|
@ -244,13 +247,13 @@ irq_hook_t *hook;
|
|||
if (next_timeout <= now || (sched_ticks == 1 && bill_ptr == prev_ptr
|
||||
&& rdy_head[PPRI_USER] != NIL_PROC))
|
||||
{
|
||||
notify(CLOCK, HARD_INT);
|
||||
lock_notify(CLOCK, HARD_INT);
|
||||
}
|
||||
else if (--sched_ticks == 0) {
|
||||
sched_ticks = SCHED_RATE; /* reset quantum */
|
||||
prev_ptr = bill_ptr; /* new previous process */
|
||||
}
|
||||
return 1; /* reenable clock interrupts */
|
||||
return(1); /* reenable clock interrupts */
|
||||
}
|
||||
|
||||
|
||||
|
@ -310,9 +313,10 @@ struct timer *tp; /* pointer to timer structure */
|
|||
*===========================================================================*/
|
||||
PRIVATE void init_clock()
|
||||
{
|
||||
/* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz. */
|
||||
static irq_hook_t clock_hook;
|
||||
/* Initialize the CLOCK's interrupt hook. */
|
||||
clock_hook.proc_nr = CLOCK;
|
||||
|
||||
/* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz. */
|
||||
outb(TIMER_MODE, SQUARE_WAVE); /* set timer to run continuously */
|
||||
outb(TIMER0, TIMER_COUNT); /* load timer low byte */
|
||||
outb(TIMER0, TIMER_COUNT >> 8); /* load timer high byte */
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/* A dummy task. Used to safely remove old tasks, and get notices if they get
|
||||
* called by accident (i.e., because of some bug...).
|
||||
*
|
||||
* Created:
|
||||
* Jul 27, 2004 by Jorrit N. Herder
|
||||
*/
|
||||
|
||||
#include "kernel.h"
|
||||
#include "proc.h"
|
||||
#include <minix/com.h>
|
||||
|
||||
/* Allocated space for the global variables. */
|
||||
message m_in; /* the input message itself */
|
||||
message m_out; /* the output message used for reply */
|
||||
int who; /* caller's proc number */
|
||||
int callnr; /* system call number */
|
||||
|
||||
/* Declare some local functions. */
|
||||
FORWARD _PROTOTYPE(void get_work, (void) );
|
||||
FORWARD _PROTOTYPE(void reply, (int whom, int result) );
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* dummy_task *
|
||||
*===========================================================================*/
|
||||
PUBLIC void dummy_task()
|
||||
{
|
||||
/* This is the main routine of this service. In principle this should block
|
||||
* forever on getting new work - the dummy task is not supposed to be called.
|
||||
* If new work is received, somehow, diagnostics are printed.
|
||||
*/
|
||||
int result;
|
||||
|
||||
/* kprintf("DUMMY: do nothing kernel task started (proc. nr %d).\n",
|
||||
proc_number(proc_ptr)); */
|
||||
|
||||
/* Main loop - get work and do it, forever. */
|
||||
while (TRUE) {
|
||||
|
||||
/* Wait for incoming message, sets 'callnr' and 'who'. */
|
||||
get_work();
|
||||
|
||||
/* There is work to do! (re)set some variables first. */
|
||||
result = EINVAL; /* illegal send to dummy task */
|
||||
|
||||
/* Print diagnostics: this was not supposed to happen. */
|
||||
kprintf("Dummy task: request received from %d.\n", who);
|
||||
|
||||
/* Finally send reply message, unless disabled. */
|
||||
if (result != EDONTREPLY) {
|
||||
reply(who, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* get_work *
|
||||
*===========================================================================*/
|
||||
PRIVATE void get_work()
|
||||
{
|
||||
int status = 0;
|
||||
status = receive(ANY, &m_in); /* this blocks until message arrives */
|
||||
if (OK != status)
|
||||
kprintf("Dummy task failed to receive message: %d", status);
|
||||
who = m_in.m_source; /* message arrived! set sender */
|
||||
callnr = m_in.m_type; /* set function call number */
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* reply *
|
||||
*===========================================================================*/
|
||||
PRIVATE void reply(who, result)
|
||||
int who; /* destination */
|
||||
int result; /* report result to replyee */
|
||||
{
|
||||
int send_status;
|
||||
m_out.m_type = result; /* build reply message */
|
||||
send_status = send(who, &m_out); /* send the message */
|
||||
if (OK != send_status)
|
||||
kprintf("Dummy task unable to send reply: %d", send_status);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ unsigned vec_nr;
|
|||
return;
|
||||
}
|
||||
|
||||
if (k_reenter == 0 && isuserp(saved_proc)) {
|
||||
if (k_reenter == 0 && ! istaskp(saved_proc)) {
|
||||
unlock(); /* this is protected like sys_call() */
|
||||
cause_sig(proc_number(saved_proc), ep->signum);
|
||||
return;
|
||||
|
|
|
@ -27,6 +27,7 @@ EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */
|
|||
EXTERN struct proc *held_head; /* head of queue of held-up interrupts */
|
||||
EXTERN struct proc *held_tail; /* tail of queue of held-up interrupts */
|
||||
EXTERN unsigned char k_reenter; /* kernel reentry count (entry count less 1)*/
|
||||
EXTERN unsigned char switching; /* nonzero if process switching in progress */
|
||||
|
||||
/* Process table. Here to stop too many things having to include proc.h. */
|
||||
EXTERN struct proc *proc_ptr; /* pointer to currently running process */
|
||||
|
|
|
@ -42,7 +42,6 @@ int mine;
|
|||
* use the BIOS locations instead. The flag "mine" is set if the 8259s are
|
||||
* to be programmed for Minix, or to be reset to what the BIOS expects.
|
||||
*/
|
||||
|
||||
int i;
|
||||
|
||||
lock();
|
||||
|
|
|
@ -160,7 +160,7 @@ int c; /* character to append */
|
|||
kmess.km_size += 1;
|
||||
kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
|
||||
} else {
|
||||
notify(TTY, NEW_KMESS); /* let TTY display the message */
|
||||
lock_notify(TTY, NEW_KMESS); /* let TTY display the message */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ int how; /* 0 = halt, 1 = reboot, 2 = panic!, ... */
|
|||
/* The TTY expects two HARD_STOP notifications. One to switch to the
|
||||
* primary console for stop sequence output, and one to actually exit.
|
||||
*/
|
||||
notify(TTY, HARD_STOP); /* let TTY switch to console 0 */
|
||||
lock_notify(TTY, HARD_STOP); /* let TTY switch to console 0 */
|
||||
|
||||
/* Run the stop sequence. The timer argument passes the shutdown status.
|
||||
* The stop sequence is skipped for fatal CPU exceptions.
|
||||
|
@ -289,7 +289,7 @@ timer_t *tp;
|
|||
kprintf("- Stopping %s ", karg(p->p_name));
|
||||
kprintf("%s ... ", karg(types[p->p_type]));
|
||||
shutdown_process = p; /* directly continue if exited */
|
||||
notify(proc_number(p), HARD_STOP);
|
||||
lock_notify(proc_number(p), HARD_STOP);
|
||||
set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
|
||||
return; /* allow the process to shut down */
|
||||
}
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
#
|
||||
! This file, mpx386.s, is included by mpx.s when Minix is compiled for
|
||||
! 32-bit Intel CPUs. The alternative mpx88.s is compiled for 16-bit CPUs.
|
||||
!
|
||||
! This contains the assembler startup code for Minix and the 32-bit
|
||||
! interrupt handlers. It cooperates with start.c to set up a good
|
||||
! environment for main().
|
||||
|
||||
! This file is part of the lowest layer of the MINIX kernel. The other part
|
||||
! is "proc.c". The lowest layer does process switching and message handling.
|
||||
! This file is part of the lowest layer of the MINIX kernel. (The other part
|
||||
! is "proc.c".) The lowest layer does process switching and message handling.
|
||||
! Furthermore it contains the assembler startup code for Minix and the 32-bit
|
||||
! interrupt handlers. It cooperates with the code in "start.c" to set up a
|
||||
! good environment for main().
|
||||
|
||||
! Every transition to the kernel goes through this file. Transitions are
|
||||
! caused by sending/receiving messages and by most interrupts. (RS232
|
||||
! interrupts may be handled in the file "rs2.s" and then they rarely enter
|
||||
! the kernel.)
|
||||
|
||||
! Transitions to the kernel may be nested. The initial entry may be with a
|
||||
! system call, exception or hardware interrupt; reentries may only be made
|
||||
! by hardware interrupts. The count of reentries is kept in "k_reenter".
|
||||
! It is important for deciding whether to switch to the kernel stack and
|
||||
! for protecting the message passing code in "proc.c".
|
||||
! Every transition to the kernel goes through this file. Transitions to the
|
||||
! kernel may be nested. The initial entry may be with a system call (i.e.,
|
||||
! send or receive a message), an exception or a hardware interrupt; kernel
|
||||
! reentries may only be made by hardware interrupts. The count of reentries
|
||||
! is kept in "k_reenter". It is important for deciding whether to switch to
|
||||
! the kernel stack and for protecting the message passing code in "proc.c".
|
||||
|
||||
! For the message passing trap, most of the machine state is saved in the
|
||||
! proc table. (Some of the registers need not be saved.) Then the stack is
|
||||
|
@ -226,7 +221,7 @@ csinit:
|
|||
outb INT_CTL /* reenable master 8259 */;\
|
||||
push (_irq_handlers+4*irq) /* irq_handlers[irq] */;\
|
||||
sti /* enable interrupts */;\
|
||||
call _intr_handle /* intr_handle(irq_handlers[irq]) */;\
|
||||
call _intr_handle /* intr_handle(irq_handlers[irq]) */;\
|
||||
cli /* disable interrupts */;\
|
||||
pop ecx ;\
|
||||
cmp (_irq_actids+4*irq), 0 /* interrupt still active? */;\
|
||||
|
@ -397,13 +392,15 @@ _p_s_call:
|
|||
!*===========================================================================*
|
||||
_restart:
|
||||
|
||||
! Flush any held-up interrupts.
|
||||
! Flush any held-up notifications.
|
||||
! This reenables interrupts, so the current interrupt handler may reenter.
|
||||
! This does not matter, because the current handler is about to exit and no
|
||||
! other handlers can reenter since flushing is only done when k_reenter == 0.
|
||||
|
||||
cmp (_held_head), 0 ! do fast test to usually avoid function call
|
||||
jz over_call_unhold
|
||||
cmp (_switching), 0 ! do fast test to usually avoid function call
|
||||
jnz over_call_unhold
|
||||
call _unhold ! this is rare so overhead acceptable
|
||||
over_call_unhold:
|
||||
mov esp, (_proc_ptr) ! will assume P_STACKBASE == 0
|
||||
|
|
111
kernel/proc.c
111
kernel/proc.c
|
@ -1,11 +1,12 @@
|
|||
/* This file contains essentially all of the process and message handling.
|
||||
* It has two main entry points from the outside:
|
||||
*
|
||||
* sys_call: a system call, that is, the kernel is trapped with an INT
|
||||
* notify: notify process of a system event (notifications aren't queued)
|
||||
* sys_call: a system call, that is, the kernel is trapped with an INT
|
||||
* lock_notify: send a notification to inform a process of a system event
|
||||
*
|
||||
* It also has several minor entry points:
|
||||
* It also has several minor entry points to be used from the task level:
|
||||
*
|
||||
* lock_send: send a message to a process
|
||||
* lock_ready: put a process on one of the ready queues so it can be run
|
||||
* lock_unready: remove a process from the ready queues
|
||||
* lock_sched: a process has run too long; schedule another one
|
||||
|
@ -31,12 +32,13 @@
|
|||
#include "proc.h"
|
||||
#include "sendmask.h"
|
||||
|
||||
PRIVATE unsigned char switching; /* nonzero to inhibit notify() */
|
||||
|
||||
FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dest,
|
||||
message *m_ptr, int may_block) );
|
||||
FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
|
||||
message *m_ptr, int may_block) );
|
||||
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dest,
|
||||
message *m_ptr ) );
|
||||
FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
|
||||
FORWARD _PROTOTYPE( void sched, (void) );
|
||||
FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
|
||||
|
@ -66,9 +68,9 @@ FORWARD _PROTOTYPE( void cp_mess, (int src, struct proc *src_p, message *src_m,
|
|||
|
||||
|
||||
/*===========================================================================*
|
||||
* notify *
|
||||
* lock_notify *
|
||||
*===========================================================================*/
|
||||
PUBLIC void notify(proc_nr, notify_type)
|
||||
PUBLIC void lock_notify(proc_nr, notify_type)
|
||||
int proc_nr; /* number of process to be started */
|
||||
int notify_type; /* notification to be sent */
|
||||
{
|
||||
|
@ -104,8 +106,19 @@ int notify_type; /* notification to be sent */
|
|||
* handler might call notify() and pass the 'k_reenter' test.
|
||||
*/
|
||||
if (k_reenter != 0 || switching) {
|
||||
lock();
|
||||
if (! rp->p_ntf_held) { /* already on held queue? */
|
||||
kinfo.notify_held ++;
|
||||
if (switching) kinfo.notify_switching ++;
|
||||
if (k_reenter > 0) kinfo.notify_reenter ++;
|
||||
switch(notify_type) {
|
||||
case HARD_INT: kinfo.notify_int ++; break;
|
||||
case HARD_STOP: kinfo.notify_stop ++; break;
|
||||
case SYN_ALARM: kinfo.notify_alarm ++; break;
|
||||
case KSIG_PENDING: kinfo.notify_sig ++; break;
|
||||
case NEW_KMESS: kinfo.notify_kmess ++; break;
|
||||
}
|
||||
lock();
|
||||
/* already on held queue? */
|
||||
if (! isset_bit(rp->p_ntf_held, notify_bit)) {
|
||||
if (held_head != NIL_PROC)
|
||||
held_tail->p_ntf_nextheld = rp;
|
||||
else
|
||||
|
@ -117,32 +130,35 @@ int notify_type; /* notification to be sent */
|
|||
unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
/* If process is not waiting for a notification, record the blockage. Else,
|
||||
* send it a message with source HARDWARE and type 'notify_type'. No more
|
||||
* information can be reliably provided since notifications are not queued.
|
||||
*/
|
||||
switching = TRUE;
|
||||
|
||||
/* If process is not waiting for a notification, record the blockage. */
|
||||
if ( (rp->p_flags & (RECEIVING | SENDING)) != RECEIVING ||
|
||||
!isrxhardware(rp->p_getfrom)) {
|
||||
set_bit(rp->p_ntf_blocked, notify_bit); /* add bit to blocked mask */
|
||||
switching = FALSE;
|
||||
return;
|
||||
kinfo.notify_blocked ++;
|
||||
set_bit(rp->p_ntf_blocked, notify_bit); /* update blocked mask */
|
||||
} else {
|
||||
|
||||
/* Assemble notification message and send it. */
|
||||
m.m_source = HARDWARE;
|
||||
m.m_type = notify_type;
|
||||
CopyMess(HARDWARE, proc_addr(HARDWARE), &m, rp, rp->p_messbuf);
|
||||
clear_bit(rp->p_ntf_blocked, notify_bit);
|
||||
rp->p_flags &= ~RECEIVING;
|
||||
kinfo.notify_ok ++;
|
||||
|
||||
/* Announce the process ready and select a fresh process to run. */
|
||||
ready(rp);
|
||||
pick_proc();
|
||||
}
|
||||
|
||||
/* Destination is waiting for a notification. Send it a message with source
|
||||
* HARDWARE and type 'notify_type'. No more information can be reliably
|
||||
* provided since notifications are not queued.
|
||||
*/
|
||||
m.m_source = HARDWARE; /* direct copy does not work for servers */
|
||||
m.m_type = notify_type;
|
||||
CopyMess(HARDWARE, proc_addr(HARDWARE), &m, rp, rp->p_messbuf);
|
||||
rp->p_flags &= ~RECEIVING;
|
||||
clear_bit(rp->p_ntf_blocked, notify_bit);
|
||||
|
||||
/* Announce the process ready and select a fresh process to run. */
|
||||
ready(rp);
|
||||
pick_proc();
|
||||
switching = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* sys_call *
|
||||
*===========================================================================*/
|
||||
|
@ -203,6 +219,9 @@ message *m_ptr; /* pointer to message in the caller's space */
|
|||
case RECEIVE:
|
||||
result = mini_rec(caller_ptr, src_dst, m_ptr, may_block);
|
||||
break;
|
||||
case NOTIFY:
|
||||
result = mini_notify(caller_ptr, src_dst, m_ptr);
|
||||
break;
|
||||
default:
|
||||
result = EBADCALL; /* illegal system call */
|
||||
}
|
||||
|
@ -366,6 +385,20 @@ int may_block; /* (dis)allow blocking */
|
|||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* mini_notify *
|
||||
*===========================================================================*/
|
||||
PRIVATE int mini_notify(caller_ptr, dst, m_ptr)
|
||||
register struct proc *caller_ptr; /* process trying to get message */
|
||||
int dst; /* which process to notify */
|
||||
message *m_ptr; /* pointer to message buffer */
|
||||
{
|
||||
kprintf("Kernel notify from %d", caller_ptr->p_nr);
|
||||
kprintf("for %d\n", dst);
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* pick_proc *
|
||||
*===========================================================================*/
|
||||
|
@ -496,6 +529,24 @@ PUBLIC void lock_pick_proc()
|
|||
switching = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*==========================================================================*
|
||||
* lock_send *
|
||||
*==========================================================================*/
|
||||
PUBLIC int lock_send(caller_ptr, dest, m_ptr)
|
||||
register struct proc *caller_ptr; /* who is trying to send a message? */
|
||||
int dest; /* to whom is message being sent? */
|
||||
message *m_ptr; /* pointer to message buffer */
|
||||
{
|
||||
/* Safe gateway to mini_send() for tasks. */
|
||||
int result;
|
||||
switching = TRUE;
|
||||
result = mini_send(caller_ptr, dest, m_ptr, FALSE);
|
||||
switching = FALSE;
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/*==========================================================================*
|
||||
* lock_ready *
|
||||
*==========================================================================*/
|
||||
|
@ -543,6 +594,8 @@ PUBLIC void unhold()
|
|||
register struct proc *rp; /* current head of held queue */
|
||||
int i;
|
||||
|
||||
kinfo.notify_unhold ++;
|
||||
|
||||
if (switching) return;
|
||||
rp = held_head;
|
||||
do {
|
||||
|
@ -552,9 +605,13 @@ PUBLIC void unhold()
|
|||
if (! rp->p_ntf_held) /* proceed to next in queue? */
|
||||
if ( (held_head = rp->p_ntf_nextheld) == NIL_PROC)
|
||||
held_tail = NIL_PROC;
|
||||
#if DEAD_CODE
|
||||
unlock(); /* reduce latency; held queue may change! */
|
||||
notify(proc_number(rp), NOTIFICATION + i);
|
||||
#endif
|
||||
lock_notify(proc_number(rp), NOTIFICATION + i);
|
||||
#if DEAD_CODE
|
||||
lock(); /* protect the held queue again */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,8 @@
|
|||
|
||||
/* Struct declarations. */
|
||||
struct proc;
|
||||
struct time_info;
|
||||
struct timer;
|
||||
|
||||
/* dummy.c */
|
||||
_PROTOTYPE( void dummy_task, (void) );
|
||||
|
||||
/* clock.c */
|
||||
_PROTOTYPE( void clock_task, (void) );
|
||||
_PROTOTYPE( void clock_stop, (void) );
|
||||
|
@ -37,20 +33,21 @@ _PROTOTYPE( void kprintf, (const char *fmt, karg_t arg) );
|
|||
|
||||
/* main.c */
|
||||
_PROTOTYPE( void main, (void) );
|
||||
_PROTOTYPE( void prepare_shutdown, (int) );
|
||||
_PROTOTYPE( void stop_sequence, (struct timer *tp) );
|
||||
_PROTOTYPE( void prepare_shutdown, (int) );
|
||||
_PROTOTYPE( void stop_sequence, (struct timer *tp) );
|
||||
|
||||
/* misc.c */
|
||||
_PROTOTYPE( void panic, (_CONST char *s, int n) );
|
||||
|
||||
/* proc.c */
|
||||
_PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) );
|
||||
_PROTOTYPE( void notify, (int proc_nr, int notify_type) );
|
||||
_PROTOTYPE( void unhold, (void) );
|
||||
_PROTOTYPE( void lock_pick_proc, (void) );
|
||||
_PROTOTYPE( void lock_ready, (struct proc *rp) );
|
||||
_PROTOTYPE( void lock_sched, (void) );
|
||||
_PROTOTYPE( void lock_unready, (struct proc *rp) );
|
||||
_PROTOTYPE( void lock_notify, (int proc_nr, int notify_type) );
|
||||
_PROTOTYPE( int lock_send, (struct proc *rp, int to, message *m_ptr) );
|
||||
|
||||
/* start.c */
|
||||
_PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
|
||||
|
|
|
@ -57,6 +57,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
|
|||
phys_copy(kinfo.params_base, vir2phys(k_environ), kinfo.params_size);
|
||||
|
||||
/* Record miscellaneous information for user-space servers. */
|
||||
kinfo.nr_procs = NR_PROCS;
|
||||
kinfo.nr_tasks = NR_TASKS;
|
||||
kstrncpy(kinfo.version, OS_RELEASE "." OS_VERSION, 6);
|
||||
kinfo.proc_addr = (vir_bytes) proc;
|
||||
kinfo.kmem_base = vir2phys(0);
|
||||
|
|
|
@ -83,10 +83,13 @@ PUBLIC void sys_task()
|
|||
result = EBADREQUEST; /* illegal message type */
|
||||
}
|
||||
|
||||
/* Send a reply, unless inhibited by a handler function. */
|
||||
/* Send a reply, unless inhibited by a handler function. Use the kernel
|
||||
* function lock_send() to prevent a system call trap. The destination
|
||||
* is known to be blocked waiting for a message.
|
||||
*/
|
||||
if (result != EDONTREPLY) {
|
||||
m.m_type = result; /* report status of call */
|
||||
send(m.m_source, &m); /* send reply to caller */
|
||||
lock_send(proc_addr(SYSTASK), m.m_source, &m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +243,7 @@ irq_hook_t *hook;
|
|||
* interrupts are transformed into messages to a driver. The IRQ line will be
|
||||
* reenabled if the policy says so.
|
||||
*/
|
||||
notify(hook->proc_nr, HARD_INT);
|
||||
lock_notify(hook->proc_nr, HARD_INT);
|
||||
return(hook->policy & IRQ_REENABLE);
|
||||
}
|
||||
|
||||
|
@ -275,7 +278,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
|
|||
return; /* another signal already pending */
|
||||
if (rp->p_flags == 0) lock_unready(rp);
|
||||
rp->p_flags |= PENDING | SIG_PENDING;
|
||||
notify(PM_PROC_NR, KSIG_PENDING);
|
||||
lock_notify(PM_PROC_NR, KSIG_PENDING);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ timer_t *tp;
|
|||
* alarm. The process number is stored in timer argument 'ta_int'. Notify that
|
||||
* process given with a SYN_ALARM message.
|
||||
*/
|
||||
notify(tmr_arg(tp)->ta_int, SYN_ALARM);
|
||||
lock_notify(tmr_arg(tp)->ta_int, SYN_ALARM);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -236,6 +236,8 @@ register message *m_ptr; /* pointer to request message */
|
|||
/* Request a (DMA) buffer to be allocated in one of the memory chunks. */
|
||||
phys_clicks tot_clicks;
|
||||
struct memory *memp;
|
||||
|
||||
kprintf("SYS_KMALLOC called by %d\n", m_ptr->m_source);
|
||||
|
||||
tot_clicks = (m_ptr->MEM_CHUNK_SIZE + CLICK_SIZE-1) >> CLICK_SHIFT;
|
||||
memp = &mem[NR_MEMS];
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define CLOCK_STACK SMALL_STACK
|
||||
|
||||
/* Stack space for all the task stacks. Declared as (char *) to align it. */
|
||||
#define TOT_STACK_SPACE (IDLE_STACK+HARDWARE_STACK+CLOCK_STACK+SYS_STACK )
|
||||
#define TOT_STACK_SPACE (IDLE_STACK+HARDWARE_STACK+CLOCK_STACK+SYS_STACK)
|
||||
PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue