Optimized scheduling code. Old code is still available withing DEAD_CODE
and NEW_SCHED_Q definitions. Some minor problems are being traced at the moment. This commit is meant to backup my files. --- Jorrit
This commit is contained in:
parent
dcffa17db2
commit
77c3213948
|
@ -869,11 +869,17 @@ message *m;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Try to get a fresh copy of the buffer with kernel messages. */
|
/* Try to get a fresh copy of the buffer with kernel messages. */
|
||||||
r=0;
|
#if DEAD_CODE
|
||||||
|
/* During shutdown, the reply is garbled because new notifications arrive
|
||||||
|
* while the system task makes a copy of the kernel messages buffer.
|
||||||
|
* Hence, don't check the return value.
|
||||||
|
*/
|
||||||
if ((r=sys_getkmessages(&kmess)) != OK) {
|
if ((r=sys_getkmessages(&kmess)) != OK) {
|
||||||
printf("TTY: couldn't get copy of kmessages: %d, 0x%x\n", r,r);
|
printf("TTY: couldn't get copy of kmessages: %d, 0x%x\n", r,r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
sys_getkmessages(&kmess);
|
||||||
|
|
||||||
/* Print only the new part. Determine how many new bytes there are with
|
/* Print only the new part. Determine how many new bytes there are with
|
||||||
* help of the current and previous 'next' index. Note that the kernel
|
* help of the current and previous 'next' index. Note that the kernel
|
||||||
|
|
|
@ -526,13 +526,23 @@ int scode; /* scan code for a function key */
|
||||||
|
|
||||||
/* See if an observer is registered and send it a message. */
|
/* See if an observer is registered and send it a message. */
|
||||||
if (observers[index] != NONE) {
|
if (observers[index] != NONE) {
|
||||||
|
#if DEAD_CODE
|
||||||
m.m_type = FKEY_PRESSED;
|
m.m_type = FKEY_PRESSED;
|
||||||
m.FKEY_NUM = index+1;
|
m.FKEY_NUM = index+1;
|
||||||
m.FKEY_CODE = fkey;
|
m.FKEY_CODE = fkey;
|
||||||
if (OK != (s=nb_send(observers[index], &m))) {
|
if (OK != (s=nb_send(observers[index], &m))) {
|
||||||
printf("WARNING: F%d key notification to process %d failed: %d.\n",
|
printf("WARNING: F%d key nb_send to process %d failed: %d.\n",
|
||||||
index+1, observers[index], s);
|
index+1, observers[index], s);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
m.NOTIFY_TYPE = FKEY_PRESSED;
|
||||||
|
m.NOTIFY_ARG = fkey;
|
||||||
|
m.NOTIFY_FLAGS = index+1;
|
||||||
|
if (OK != (s=notify(observers[index], &m))) {
|
||||||
|
printf("WARNING: F%d key notify to process %d failed: %d.\n",
|
||||||
|
index+1, observers[index], s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,7 @@ PUBLIC timer_t *tty_timers; /* queue of TTY timers */
|
||||||
PUBLIC clock_t tty_next_timeout; /* time that the next alarm is due */
|
PUBLIC clock_t tty_next_timeout; /* time that the next alarm is due */
|
||||||
PUBLIC struct machine machine; /* kernel environment variables */
|
PUBLIC struct machine machine; /* kernel environment variables */
|
||||||
|
|
||||||
|
static int debug = 0;
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* tty_task *
|
* tty_task *
|
||||||
|
@ -192,6 +193,11 @@ PUBLIC void main(void)
|
||||||
* request and should be handled separately. These extra functions
|
* request and should be handled separately. These extra functions
|
||||||
* do not operate on a device, in constrast to the driver requests.
|
* do not operate on a device, in constrast to the driver requests.
|
||||||
*/
|
*/
|
||||||
|
if (debug) {
|
||||||
|
printf("TTY got request from %d, type %d\n",
|
||||||
|
tty_mess.m_source, tty_mess.m_type);
|
||||||
|
printf("???\n");
|
||||||
|
}
|
||||||
switch (tty_mess.m_type) {
|
switch (tty_mess.m_type) {
|
||||||
case SYN_ALARM: /* fall through */
|
case SYN_ALARM: /* fall through */
|
||||||
case HARD_INT: /* hardware interrupt notification */
|
case HARD_INT: /* hardware interrupt notification */
|
||||||
|
@ -204,8 +210,12 @@ PUBLIC void main(void)
|
||||||
case HARD_STOP: { /* MINIX is going down */
|
case HARD_STOP: { /* MINIX is going down */
|
||||||
static int stop = 0; /* expect two HARD_STOP messages */
|
static int stop = 0; /* expect two HARD_STOP messages */
|
||||||
if (! stop++) {
|
if (! stop++) {
|
||||||
|
printf("TTY got first HARD_STOP message\n");
|
||||||
|
debug = 1;
|
||||||
cons_stop(); /* first switch to primary console */
|
cons_stop(); /* first switch to primary console */
|
||||||
|
printf("TTY returned from cons_stop()\n");
|
||||||
} else {
|
} else {
|
||||||
|
printf("TTY got second HARD_STOP message\n");
|
||||||
if(irq_hook_id != -1) {
|
if(irq_hook_id != -1) {
|
||||||
int r;
|
int r;
|
||||||
r = sys_irqdisable(&irq_hook_id);
|
r = sys_irqdisable(&irq_hook_id);
|
||||||
|
@ -222,7 +232,9 @@ PUBLIC void main(void)
|
||||||
do_panic_dumps(&tty_mess);
|
do_panic_dumps(&tty_mess);
|
||||||
continue;
|
continue;
|
||||||
case DIAGNOSTICS: /* a server wants to print some */
|
case DIAGNOSTICS: /* a server wants to print some */
|
||||||
|
if (debug) printf("TTY get DIAG\n");
|
||||||
do_diagnostics(&tty_mess);
|
do_diagnostics(&tty_mess);
|
||||||
|
if (debug) printf("TTY finished DIAG\n");
|
||||||
continue;
|
continue;
|
||||||
case FKEY_CONTROL: /* (un)register a fkey observer */
|
case FKEY_CONTROL: /* (un)register a fkey observer */
|
||||||
do_fkey_ctl(&tty_mess);
|
do_fkey_ctl(&tty_mess);
|
||||||
|
@ -1302,8 +1314,12 @@ int status; /* reply code */
|
||||||
tty_mess.m_type = code;
|
tty_mess.m_type = code;
|
||||||
tty_mess.REP_PROC_NR = proc_nr;
|
tty_mess.REP_PROC_NR = proc_nr;
|
||||||
tty_mess.REP_STATUS = status;
|
tty_mess.REP_STATUS = status;
|
||||||
if ((status = send(replyee, &tty_mess)) != OK)
|
if (debug)
|
||||||
|
printf("TTY wanted to send to %d, type %d, status %d\n",
|
||||||
|
proc_nr, code, status);
|
||||||
|
if ((status = send(replyee, &tty_mess)) != OK) {
|
||||||
server_panic("TTY","tty_reply failed, status\n", status);
|
server_panic("TTY","tty_reply failed, status\n", status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ PUBLIC void clock_task()
|
||||||
result = do_clocktick(&m); /* handle clock tick */
|
result = do_clocktick(&m); /* handle clock tick */
|
||||||
break;
|
break;
|
||||||
default: /* illegal message type */
|
default: /* illegal message type */
|
||||||
kprintf("CLOCK got illegal request from %d.\n", m.m_source);
|
kprintf("Warning, illegal CLOCK request from %d.\n", m.m_source);
|
||||||
result = EBADREQUEST;
|
result = EBADREQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,8 @@ PUBLIC void clock_task()
|
||||||
*/
|
*/
|
||||||
if (result != EDONTREPLY) {
|
if (result != EDONTREPLY) {
|
||||||
m.m_type = result;
|
m.m_type = result;
|
||||||
lock_send(m.m_source, &m);
|
if (OK != lock_send(m.m_source, &m))
|
||||||
|
kprintf("Warning, CLOCK couldn't reply to %d.\n", m.m_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,9 +156,10 @@ message *m_ptr; /* pointer to request message */
|
||||||
TMR_NEVER : clock_timers->tmr_exp_time;
|
TMR_NEVER : clock_timers->tmr_exp_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a user process has been running too long, pick another one. */
|
/* If a process has been running too long, pick another one. */
|
||||||
if (--sched_ticks == 0) {
|
if (--sched_ticks <= 0) {
|
||||||
if (bill_ptr == prev_ptr) lock_sched(); /* process has run too long */
|
if (bill_ptr == prev_ptr)
|
||||||
|
lock_sched(PPRI_USER); /* process has run too long */
|
||||||
sched_ticks = SCHED_RATE; /* reset quantum */
|
sched_ticks = SCHED_RATE; /* reset quantum */
|
||||||
prev_ptr = bill_ptr; /* new previous process */
|
prev_ptr = bill_ptr; /* new previous process */
|
||||||
}
|
}
|
||||||
|
@ -249,7 +251,7 @@ irq_hook_t *hook;
|
||||||
m.NOTIFY_TYPE = HARD_INT;
|
m.NOTIFY_TYPE = HARD_INT;
|
||||||
lock_notify(CLOCK, &m);
|
lock_notify(CLOCK, &m);
|
||||||
}
|
}
|
||||||
else if (--sched_ticks == 0) {
|
else if (--sched_ticks <= 0) {
|
||||||
sched_ticks = SCHED_RATE; /* reset the quantum */
|
sched_ticks = SCHED_RATE; /* reset the quantum */
|
||||||
prev_ptr = bill_ptr; /* new previous process */
|
prev_ptr = bill_ptr; /* new previous process */
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ unsigned vec_nr;
|
||||||
|
|
||||||
if (k_reenter == 0 && ! istaskp(saved_proc)) {
|
if (k_reenter == 0 && ! istaskp(saved_proc)) {
|
||||||
unlock(); /* this is protected like sys_call() */
|
unlock(); /* this is protected like sys_call() */
|
||||||
cause_sig(proc_number(saved_proc), ep->signum);
|
cause_sig(proc_nr(saved_proc), ep->signum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ unsigned vec_nr;
|
||||||
kprintf("\nIntel-reserved exception %d\n", vec_nr);
|
kprintf("\nIntel-reserved exception %d\n", vec_nr);
|
||||||
else
|
else
|
||||||
kprintf("\n%s\n", karg(ep->msg));
|
kprintf("\n%s\n", karg(ep->msg));
|
||||||
kprintf("process number %d, ", proc_number(saved_proc));
|
kprintf("process number %d, ", proc_nr(saved_proc));
|
||||||
kprintf("pc = %d:", (unsigned) saved_proc->p_reg.cs);
|
kprintf("pc = %d:", (unsigned) saved_proc->p_reg.cs);
|
||||||
kprintf("0x%x\n", (unsigned) saved_proc->p_reg.pc);
|
kprintf("0x%x\n", (unsigned) saved_proc->p_reg.pc);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ PUBLIC void main()
|
||||||
intr_init(1);
|
intr_init(1);
|
||||||
|
|
||||||
/* Clear the process table. Anounce each slot as empty and
|
/* Clear the process table. Anounce each slot as empty and
|
||||||
* set up mappings for proc_addr() and proc_number() macros.
|
* set up mappings for proc_addr() and proc_nr() macros.
|
||||||
*/
|
*/
|
||||||
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
|
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
|
||||||
rp->p_type = P_NONE; /* isemptyp() tests on this */
|
rp->p_type = P_NONE; /* isemptyp() tests on this */
|
||||||
|
@ -146,7 +146,6 @@ PUBLIC void main()
|
||||||
#if ENABLE_K_DEBUGGING
|
#if ENABLE_K_DEBUGGING
|
||||||
rp->p_ready = 0;
|
rp->p_ready = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rp->p_nr != HARDWARE) lock_ready(rp);
|
if (rp->p_nr != HARDWARE) lock_ready(rp);
|
||||||
rp->p_flags = 0;
|
rp->p_flags = 0;
|
||||||
|
|
||||||
|
@ -271,7 +270,6 @@ timer_t *tp;
|
||||||
*/
|
*/
|
||||||
static int level = P_SERVER; /* start at the highest level */
|
static int level = P_SERVER; /* start at the highest level */
|
||||||
static struct proc *p = NIL_PROC; /* next process to stop */
|
static struct proc *p = NIL_PROC; /* next process to stop */
|
||||||
static char *types[] = {"task","system","driver","server","user"};
|
|
||||||
static message m;
|
static message m;
|
||||||
|
|
||||||
/* See if the last process' shutdown was successful. Else, force exit. */
|
/* See if the last process' shutdown was successful. Else, force exit. */
|
||||||
|
@ -291,13 +289,11 @@ timer_t *tp;
|
||||||
if (p == NIL_PROC) p = BEG_PROC_ADDR;
|
if (p == NIL_PROC) p = BEG_PROC_ADDR;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (isalivep(p) && p->p_type == level) { /* found a process */
|
if (isalivep(p) && p->p_type == level) { /* found a process */
|
||||||
int w;
|
kprintf("- Stopping %s ... ", karg(p->p_name));
|
||||||
kprintf("- Stopping %s ", karg(p->p_name));
|
|
||||||
kprintf("%s ... ", karg(types[p->p_type]));
|
|
||||||
shutdown_process = p; /* directly continue if exited */
|
shutdown_process = p; /* directly continue if exited */
|
||||||
m.NOTIFY_TYPE = HARD_STOP;
|
m.NOTIFY_TYPE = HARD_STOP;
|
||||||
m.NOTIFY_ARG = tmr_arg(tp)->ta_int; /* how */
|
m.NOTIFY_ARG = tmr_arg(tp)->ta_int; /* how */
|
||||||
lock_notify(proc_number(p), &m);
|
lock_notify(proc_nr(p), &m);
|
||||||
set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
|
set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
|
||||||
return; /* allow the process to shut down */
|
return; /* allow the process to shut down */
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,6 @@ bit_t nr_bits;
|
||||||
return(bit_nr);
|
return(bit_nr);
|
||||||
|
|
||||||
}
|
}
|
||||||
kprintf("Warning, all %d bits in map busy\n", nr_bits);
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
350
kernel/proc.c
350
kernel/proc.c
|
@ -1,3 +1,4 @@
|
||||||
|
#define NEW_SCHED_Q 1
|
||||||
/* This file contains essentially all of the process and message handling.
|
/* This file contains essentially all of the process and message handling.
|
||||||
* It has one main entry point from the outside:
|
* It has one main entry point from the outside:
|
||||||
*
|
*
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
* lock_pick_proc: pick a process to run (used by system initialization)
|
* lock_pick_proc: pick a process to run (used by system initialization)
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
|
* May 26, 2005 optimized message passing functions (Jorrit N. Herder)
|
||||||
* May 24, 2005 new, queued NOTIFY system call (Jorrit N. Herder)
|
* May 24, 2005 new, queued NOTIFY system call (Jorrit N. Herder)
|
||||||
* Oct 28, 2004 non-blocking SEND and RECEIVE (Jorrit N. Herder)
|
* Oct 28, 2004 non-blocking SEND and RECEIVE (Jorrit N. Herder)
|
||||||
* Oct 28, 2004 rewrite of sys_call() (Jorrit N. Herder)
|
* Oct 28, 2004 rewrite of sys_call() (Jorrit N. Herder)
|
||||||
|
@ -33,21 +35,22 @@
|
||||||
* interrupts to prevent race conditions.
|
* interrupts to prevent race conditions.
|
||||||
*/
|
*/
|
||||||
FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst,
|
FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst,
|
||||||
message *m_ptr, int may_block) );
|
message *m_ptr, int flags) );
|
||||||
FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
|
FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
|
||||||
message *m_ptr, int may_block) );
|
message *m_ptr, int flags) );
|
||||||
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst,
|
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst,
|
||||||
message *m_ptr ) );
|
message *m_ptr ) );
|
||||||
|
|
||||||
FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
|
FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
|
||||||
FORWARD _PROTOTYPE( void sched, (void) );
|
FORWARD _PROTOTYPE( void sched, (int queue) );
|
||||||
FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
|
FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
|
||||||
FORWARD _PROTOTYPE( void pick_proc, (void) );
|
FORWARD _PROTOTYPE( void pick_proc, (void) );
|
||||||
|
|
||||||
#if (CHIP == M68000)
|
#define BuildMess(m,n) \
|
||||||
FORWARD _PROTOTYPE( void cp_mess, (int src, struct proc *src_p, message *src_m,
|
(m).NOTIFY_SOURCE = (n)->n_source, \
|
||||||
struct proc *dst_p, message *dst_m) );
|
(m).NOTIFY_TYPE = (n)->n_type, \
|
||||||
#endif
|
(m).NOTIFY_FLAGS = (n)->n_flags, \
|
||||||
|
(m).NOTIFY_ARG = (n)->n_arg;
|
||||||
|
|
||||||
#if (CHIP == INTEL)
|
#if (CHIP == INTEL)
|
||||||
#define CopyMess(s,sp,sm,dp,dm) \
|
#define CopyMess(s,sp,sm,dp,dm) \
|
||||||
|
@ -80,61 +83,77 @@ message *m_ptr; /* pointer to message in the caller's space */
|
||||||
*/
|
*/
|
||||||
register struct proc *caller_ptr = proc_ptr; /* get pointer to caller */
|
register struct proc *caller_ptr = proc_ptr; /* get pointer to caller */
|
||||||
int function = call_nr & SYSCALL_FUNC; /* get system call function */
|
int function = call_nr & SYSCALL_FUNC; /* get system call function */
|
||||||
int may_block = ! (call_nr & NON_BLOCKING); /* (dis)allow blocking? */
|
int flags = call_nr & SYSCALL_FLAGS; /* get flags */
|
||||||
int mask_entry; /* bit to check in send mask */
|
int mask_entry; /* bit to check in send mask */
|
||||||
int result; /* the system call's result */
|
int result; /* the system call's result */
|
||||||
|
vir_bytes vb; /* message buffer pointer as vir_bytes */
|
||||||
|
vir_clicks vlo, vhi; /* virtual clicks containing message to send */
|
||||||
|
|
||||||
/* Calls directed to the kernel may only be sendrec(), because tasks always
|
/* Calls directed to the kernel may only be sendrec(), because tasks always
|
||||||
* reply and may not block if the caller doesn't do receive(). Users also
|
* reply and may not block if the caller doesn't do receive(). Users also
|
||||||
* may only use sendrec() to protect the process manager and file system.
|
* may only use sendrec() to protect the process manager and file system.
|
||||||
*/
|
*/
|
||||||
#if DEAD_CODE
|
if (iskernel(src_dst) && function != BOTH)
|
||||||
if ((iskernel(src_dst) || isuserp(caller_ptr)) && function != BOTH) {
|
return(ECALLDENIED); /* BOTH was required */
|
||||||
#else
|
|
||||||
if (iskernel(src_dst) && function != BOTH) {
|
|
||||||
#endif
|
|
||||||
result = ECALLDENIED; /* BOTH was required */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that requested source and/ or destination is a valid process. */
|
/* Verify that requested source and/ or destination is a valid process. */
|
||||||
else if (! isoksrc_dst(src_dst)) {
|
if (! isoksrc_dst(src_dst))
|
||||||
result = EBADSRCDST; /* invalid process number */
|
return(EBADSRCDST);
|
||||||
}
|
|
||||||
|
/* Check validity of message pointer. */
|
||||||
|
vb = (vir_bytes) m_ptr;
|
||||||
|
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
|
||||||
|
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
|
||||||
|
#if ALLOW_GAP_MESSAGES
|
||||||
|
/* This check allows a message to be anywhere in data or stack or gap.
|
||||||
|
* It will have to be made more elaborate later for machines which
|
||||||
|
* don't have the gap mapped.
|
||||||
|
*/
|
||||||
|
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
|
||||||
|
vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len)
|
||||||
|
return(EFAULT);
|
||||||
|
#else
|
||||||
|
/* Check for messages wrapping around top of memory or outside data seg. */
|
||||||
|
if (vhi < vlo ||
|
||||||
|
vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len)
|
||||||
|
return(EFAULT);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now check if the call is known and try to perform the request. The only
|
/* Now check if the call is known and try to perform the request. The only
|
||||||
* system calls that exist in MINIX are sending and receiving messages.
|
* system calls that exist in MINIX are sending and receiving messages.
|
||||||
* Receiving is straightforward. Sending requires to check caller's send
|
* Receiving is straightforward. Sending requires to check caller's send
|
||||||
* mask and whether the destination is alive.
|
* mask and whether the destination is alive.
|
||||||
*/
|
*/
|
||||||
else {
|
switch(function) {
|
||||||
switch(function) {
|
case SEND:
|
||||||
case SEND:
|
/* fall through, SEND is done in BOTH */
|
||||||
/* fall through, SEND is done in BOTH */
|
case BOTH:
|
||||||
case BOTH:
|
if (! isalive(src_dst)) {
|
||||||
if (! isalive(src_dst)) {
|
result = EDEADDST; /* cannot send to the dead */
|
||||||
result = EDEADDST; /* cannot send to the dead */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst;
|
|
||||||
if (! isallowed(caller_ptr->p_sendmask, mask_entry)) {
|
|
||||||
kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr);
|
|
||||||
kprintf("sending to %d\n", proc_addr(src_dst)->p_nr);
|
|
||||||
result = ECALLDENIED; /* call denied by send mask */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = mini_send(caller_ptr, src_dst, m_ptr, may_block);
|
|
||||||
if (function == SEND || result != OK) {
|
|
||||||
break; /* done, or SEND failed */
|
|
||||||
} /* fall through for BOTH */
|
|
||||||
case RECEIVE:
|
|
||||||
result = mini_rec(caller_ptr, src_dst, m_ptr, may_block);
|
|
||||||
break;
|
break;
|
||||||
case NOTIFY:
|
|
||||||
result = mini_notify(caller_ptr, src_dst, m_ptr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = EBADCALL; /* illegal system call */
|
|
||||||
}
|
}
|
||||||
|
mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst;
|
||||||
|
if (! isallowed(caller_ptr->p_sendmask, mask_entry)) {
|
||||||
|
kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr);
|
||||||
|
kprintf("sending to %d\n", proc_addr(src_dst)->p_nr);
|
||||||
|
result = ECALLDENIED; /* call denied by send mask */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mini_send(caller_ptr, src_dst, m_ptr,
|
||||||
|
! (flags & NON_BLOCKING) );
|
||||||
|
if (function == SEND || result != OK) {
|
||||||
|
break; /* done, or SEND failed */
|
||||||
|
} /* fall through for BOTH */
|
||||||
|
case RECEIVE:
|
||||||
|
result = mini_rec(caller_ptr, src_dst, m_ptr,
|
||||||
|
! (flags & NON_BLOCKING) );
|
||||||
|
break;
|
||||||
|
case NOTIFY:
|
||||||
|
result = mini_notify(caller_ptr, src_dst, m_ptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = EBADCALL; /* illegal system call */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, return the result of the system call to the caller. */
|
/* Now, return the result of the system call to the caller. */
|
||||||
|
@ -145,44 +164,28 @@ message *m_ptr; /* pointer to message in the caller's space */
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* mini_send *
|
* mini_send *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int mini_send(caller_ptr, dst, m_ptr, may_block)
|
PRIVATE int mini_send(caller_ptr, dst, m_ptr, flags)
|
||||||
register struct proc *caller_ptr; /* who is trying to send a message? */
|
register struct proc *caller_ptr; /* who is trying to send a message? */
|
||||||
int dst; /* to whom is message being sent? */
|
int dst; /* to whom is message being sent? */
|
||||||
message *m_ptr; /* pointer to message buffer */
|
message *m_ptr; /* pointer to message buffer */
|
||||||
int may_block; /* (dis)allow blocking */
|
int flags; /* system call flags */
|
||||||
{
|
{
|
||||||
/* Send a message from 'caller_ptr' to 'dst'. If 'dst' is blocked waiting
|
/* Send a message from 'caller_ptr' to 'dst'. If 'dst' is blocked waiting
|
||||||
* for this message, copy the message to it and unblock 'dst'. If 'dst' is
|
* for this message, copy the message to it and unblock 'dst'. If 'dst' is
|
||||||
* not waiting at all, or is waiting for another source, queue 'caller_ptr'.
|
* not waiting at all, or is waiting for another source, queue 'caller_ptr'.
|
||||||
*/
|
*/
|
||||||
register struct proc *dst_ptr, *next_ptr;
|
register struct proc *dst_ptr;
|
||||||
vir_bytes vb; /* message buffer pointer as vir_bytes */
|
#if DEAD_CODE
|
||||||
vir_clicks vlo, vhi; /* virtual clicks containing message to send */
|
register struct proc *next_ptr;
|
||||||
|
#endif
|
||||||
|
register struct proc *xp;
|
||||||
|
register struct proc **xpp;
|
||||||
|
|
||||||
dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */
|
dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */
|
||||||
|
|
||||||
#if ALLOW_GAP_MESSAGES
|
/* Check for deadlock by 'caller_ptr' and 'dst' sending to each other.
|
||||||
/* This check allows a message to be anywhere in data or stack or gap.
|
* This check is rare, so overhead is acceptable.
|
||||||
* It will have to be made more elaborate later for machines which
|
|
||||||
* don't have the gap mapped.
|
|
||||||
*/
|
*/
|
||||||
vb = (vir_bytes) m_ptr;
|
|
||||||
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
|
|
||||||
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
|
|
||||||
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
|
|
||||||
vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len)
|
|
||||||
return(EFAULT);
|
|
||||||
#else
|
|
||||||
/* Check for messages wrapping around top of memory or outside data seg. */
|
|
||||||
vb = (vir_bytes) m_ptr;
|
|
||||||
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
|
|
||||||
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
|
|
||||||
if (vhi < vlo ||
|
|
||||||
vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len)
|
|
||||||
return(EFAULT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */
|
|
||||||
if (dst_ptr->p_flags & SENDING) {
|
if (dst_ptr->p_flags & SENDING) {
|
||||||
next_ptr = proc_addr(dst_ptr->p_sendto);
|
next_ptr = proc_addr(dst_ptr->p_sendto);
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -194,16 +197,17 @@ int may_block; /* (dis)allow blocking */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if 'dst' is blocked waiting for this message. */
|
/* Check if 'dst' is blocked waiting for this message. The destination's
|
||||||
|
* SENDING flag may be set when BOTH couldn't send. Await a pure RECEIVE.
|
||||||
|
*/
|
||||||
if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
|
if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
|
||||||
(dst_ptr->p_getfrom == ANY ||
|
(dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
|
||||||
dst_ptr->p_getfrom == proc_number(caller_ptr))) {
|
|
||||||
/* Destination is indeed waiting for this message. */
|
/* Destination is indeed waiting for this message. */
|
||||||
CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dst_ptr,
|
CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr,
|
||||||
dst_ptr->p_messbuf);
|
dst_ptr->p_messbuf);
|
||||||
dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */
|
dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */
|
||||||
if (dst_ptr->p_flags == 0) ready(dst_ptr);
|
if (dst_ptr->p_flags == 0) ready(dst_ptr);
|
||||||
} else if (may_block) {
|
} else if (flags) {
|
||||||
/* Destination is not waiting. Block and queue caller. */
|
/* Destination is not waiting. Block and queue caller. */
|
||||||
caller_ptr->p_messbuf = m_ptr;
|
caller_ptr->p_messbuf = m_ptr;
|
||||||
if (caller_ptr->p_flags == 0) unready(caller_ptr);
|
if (caller_ptr->p_flags == 0) unready(caller_ptr);
|
||||||
|
@ -211,14 +215,20 @@ int may_block; /* (dis)allow blocking */
|
||||||
caller_ptr->p_sendto = dst;
|
caller_ptr->p_sendto = dst;
|
||||||
|
|
||||||
/* Process is now blocked. Put in on the destination's queue. */
|
/* Process is now blocked. Put in on the destination's queue. */
|
||||||
|
#if DEAD_CODE
|
||||||
if ( (next_ptr = dst_ptr->p_caller_q) == NIL_PROC)
|
if ( (next_ptr = dst_ptr->p_caller_q) == NIL_PROC)
|
||||||
dst_ptr->p_caller_q = caller_ptr;
|
dst_ptr->p_caller_q = caller_ptr;
|
||||||
else {
|
else {
|
||||||
while (next_ptr->p_sendlink != NIL_PROC)
|
while (next_ptr->p_q_link != NIL_PROC)
|
||||||
next_ptr = next_ptr->p_sendlink;
|
next_ptr = next_ptr->p_q_link;
|
||||||
next_ptr->p_sendlink = caller_ptr;
|
next_ptr->p_q_link = caller_ptr;
|
||||||
}
|
}
|
||||||
caller_ptr->p_sendlink = NIL_PROC;
|
#else
|
||||||
|
xpp = &dst_ptr->p_caller_q;
|
||||||
|
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_q_link;
|
||||||
|
*xpp = caller_ptr;
|
||||||
|
#endif
|
||||||
|
caller_ptr->p_q_link = NIL_PROC;
|
||||||
} else {
|
} else {
|
||||||
return(ENOTREADY);
|
return(ENOTREADY);
|
||||||
}
|
}
|
||||||
|
@ -228,69 +238,89 @@ int may_block; /* (dis)allow blocking */
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* mini_rec *
|
* mini_rec *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int mini_rec(caller_ptr, src, m_ptr, may_block)
|
PRIVATE int mini_rec(caller_ptr, src, m_ptr, flags)
|
||||||
register struct proc *caller_ptr; /* process trying to get message */
|
register struct proc *caller_ptr; /* process trying to get message */
|
||||||
int src; /* which message source is wanted */
|
int src; /* which message source is wanted */
|
||||||
message *m_ptr; /* pointer to message buffer */
|
message *m_ptr; /* pointer to message buffer */
|
||||||
int may_block; /* (dis)allow blocking */
|
int flags; /* system call flags */
|
||||||
{
|
{
|
||||||
/* A process or task wants to get a message. If one is already queued,
|
/* A process or task wants to get a message. If one is already queued,
|
||||||
* acquire it and deblock the sender. If no message from the desired source
|
* acquire it and deblock the sender. If no message from the desired source
|
||||||
* is available, block the caller.
|
* is available, block the caller.
|
||||||
*/
|
*/
|
||||||
|
#if DEAD_CODE
|
||||||
register struct proc *sender_ptr;
|
register struct proc *sender_ptr;
|
||||||
register struct proc *previous_ptr;
|
register struct proc *previous_ptr;
|
||||||
|
#endif
|
||||||
|
register struct proc **xpp;
|
||||||
register struct notification **ntf_q_pp;
|
register struct notification **ntf_q_pp;
|
||||||
message m;
|
message m;
|
||||||
int bit_nr, i;
|
int bit_nr;
|
||||||
|
|
||||||
/* Check to see if a message from desired source is already available. */
|
/* Check to see if a message from desired source is already available.
|
||||||
|
* The caller's SENDING flag may be set if BOTH couldn't send. If it is
|
||||||
|
* set, the process should be blocked.
|
||||||
|
*/
|
||||||
if (!(caller_ptr->p_flags & SENDING)) {
|
if (!(caller_ptr->p_flags & SENDING)) {
|
||||||
|
|
||||||
/* Check caller queue. */
|
/* Check caller queue. Use pointer pointers to keep code simple. */
|
||||||
|
#if DEAD_CODE /* to hairy, unreadable */
|
||||||
for (sender_ptr = caller_ptr->p_caller_q; sender_ptr != NIL_PROC;
|
for (sender_ptr = caller_ptr->p_caller_q; sender_ptr != NIL_PROC;
|
||||||
previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_sendlink) {
|
previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_q_link) {
|
||||||
if (src == ANY || src == proc_number(sender_ptr)) {
|
if (src == ANY || src == proc_nr(sender_ptr)) {
|
||||||
/* An acceptable message has been found. */
|
/* An acceptable message has been found. */
|
||||||
CopyMess(proc_number(sender_ptr), sender_ptr,
|
CopyMess(sender_ptr->p_nr, sender_ptr,
|
||||||
sender_ptr->p_messbuf, caller_ptr, m_ptr);
|
sender_ptr->p_messbuf, caller_ptr, m_ptr);
|
||||||
if (sender_ptr == caller_ptr->p_caller_q)
|
if (sender_ptr == caller_ptr->p_caller_q)
|
||||||
caller_ptr->p_caller_q = sender_ptr->p_sendlink;
|
caller_ptr->p_caller_q = sender_ptr->p_q_link;
|
||||||
else
|
else
|
||||||
previous_ptr->p_sendlink = sender_ptr->p_sendlink;
|
previous_ptr->p_q_link = sender_ptr->p_q_link;
|
||||||
if ((sender_ptr->p_flags &= ~SENDING) == 0)
|
if ((sender_ptr->p_flags &= ~SENDING) == 0)
|
||||||
ready(sender_ptr); /* deblock sender */
|
ready(sender_ptr); /* deblock sender */
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
xpp = &caller_ptr->p_caller_q;
|
||||||
|
while (*xpp != NIL_PROC) {
|
||||||
|
if (src == ANY || src == proc_nr(*xpp)) {
|
||||||
|
/* An acceptable source has been found. Copy the message to the
|
||||||
|
* caller, update the sender's status, and remove the sender from
|
||||||
|
* the caller's queue.
|
||||||
|
*/
|
||||||
|
CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
|
||||||
|
if (((*xpp)->p_flags &= ~SENDING) == 0) ready(*xpp);
|
||||||
|
*xpp = (*xpp)->p_q_link; /* remove from queue */
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
xpp = &(*xpp)->p_q_link; /* proceed to next */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Check if there are pending notifications. */
|
/* Check if there are pending notifications. */
|
||||||
ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */
|
ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */
|
||||||
while (*ntf_q_pp) {
|
while (*ntf_q_pp != NULL) {
|
||||||
if (src == ANY || src == (*ntf_q_pp)->n_source) {
|
if (src == ANY || src == (*ntf_q_pp)->n_source) {
|
||||||
/* Found notification. Assemble and copy message. */
|
/* Found notification. Assemble and copy message. */
|
||||||
m.NOTIFY_SOURCE = (*ntf_q_pp)->n_source;
|
BuildMess(m, *ntf_q_pp);
|
||||||
m.NOTIFY_TYPE = (*ntf_q_pp)->n_type;
|
|
||||||
m.NOTIFY_FLAGS = (*ntf_q_pp)->n_flags;
|
|
||||||
m.NOTIFY_ARG = (*ntf_q_pp)->n_arg;
|
|
||||||
CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m,
|
CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m,
|
||||||
caller_ptr, m_ptr);
|
caller_ptr, m_ptr);
|
||||||
/* Remove notification from queue and return. */
|
/* Remove notification from queue and bit map. */
|
||||||
bit_nr = ((long)(*ntf_q_pp) - (long) ¬ify_buffer[0]) /
|
bit_nr = ((long)(*ntf_q_pp) - (long) ¬ify_buffer[0]) /
|
||||||
sizeof(struct notification);
|
sizeof(struct notification);
|
||||||
*ntf_q_pp = (*ntf_q_pp)->n_next;/* remove from queue */
|
*ntf_q_pp = (*ntf_q_pp)->n_next;/* remove from queue */
|
||||||
free_bit(bit_nr, notify_bitmap, NR_NOTIFY_BUFS);
|
free_bit(bit_nr, notify_bitmap, NR_NOTIFY_BUFS);
|
||||||
kinfo.nr_ntf_pending --;
|
|
||||||
return(OK); /* report success */
|
return(OK); /* report success */
|
||||||
}
|
}
|
||||||
ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */
|
ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No suitable message is available. Block the process trying to receive,
|
/* No suitable message is available or the caller couldn't send in BOTH.
|
||||||
* unless this is not allowed by the system call.
|
* Block the process trying to receive, unless the flags tell otherwise.
|
||||||
*/
|
*/
|
||||||
if (may_block) {
|
if (flags) {
|
||||||
caller_ptr->p_getfrom = src;
|
caller_ptr->p_getfrom = src;
|
||||||
caller_ptr->p_messbuf = m_ptr;
|
caller_ptr->p_messbuf = m_ptr;
|
||||||
if (caller_ptr->p_flags == 0) unready(caller_ptr);
|
if (caller_ptr->p_flags == 0) unready(caller_ptr);
|
||||||
|
@ -316,51 +346,53 @@ message *m_ptr; /* pointer to message buffer */
|
||||||
int ntf_index;
|
int ntf_index;
|
||||||
message ntf_mess;
|
message ntf_mess;
|
||||||
|
|
||||||
/* Check to see if target is blocked waiting for this message. */
|
/* Check to see if target is blocked waiting for this message. A process
|
||||||
|
* can be both sending and receiving during a BOTH system call.
|
||||||
|
*/
|
||||||
if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
|
if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
|
||||||
(dst_ptr->p_getfrom == ANY ||
|
(dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
|
||||||
dst_ptr->p_getfrom == proc_number(caller_ptr))) {
|
|
||||||
|
|
||||||
/* Destination is indeed waiting for this message. */
|
/* Destination is indeed waiting for this message. */
|
||||||
CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dst_ptr,
|
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
|
||||||
dst_ptr->p_messbuf);
|
dst_ptr, dst_ptr->p_messbuf);
|
||||||
dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */
|
dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */
|
||||||
if (dst_ptr->p_flags == 0) ready(dst_ptr);
|
if (dst_ptr->p_flags == 0) ready(dst_ptr);
|
||||||
}
|
}
|
||||||
/* Destination is not ready. Add the notification to the pending queue. */
|
/* Destination is not ready. Add the notification to the pending queue. */
|
||||||
else {
|
else {
|
||||||
/* Get pointer to notification message. */
|
/* Get pointer to notification message. Don't copy for kernel. */
|
||||||
if (! istaskp(caller_ptr)) {
|
if (! iskernelp(caller_ptr)) {
|
||||||
CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr,
|
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
|
||||||
proc_addr(HARDWARE), &ntf_mess);
|
proc_addr(HARDWARE), &ntf_mess);
|
||||||
m_ptr = &ntf_mess;
|
m_ptr = &ntf_mess;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue the message. Existing notifications are overwritten with
|
/* Enqueue the message. Existing notifications with the same source
|
||||||
* the newer one. New notifications are added to the end of the list.
|
* 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;
|
ntf_q_pp = &dst_ptr->p_ntf_q;
|
||||||
while (*ntf_q_pp) {
|
while (*ntf_q_pp != NULL) {
|
||||||
/* Replace notifications with same source and type. */
|
/* Replace notifications with same source and type. */
|
||||||
if ((*ntf_q_pp)->n_type == m_ptr->m_type &&
|
if ((*ntf_q_pp)->n_type == m_ptr->NOTIFY_TYPE &&
|
||||||
(*ntf_q_pp)->n_source == m_ptr->m_source) {
|
(*ntf_q_pp)->n_source == proc_nr(caller_ptr)) {
|
||||||
(*ntf_q_pp)->n_flags = m_ptr->NOTIFY_FLAGS;
|
(*ntf_q_pp)->n_flags = m_ptr->NOTIFY_FLAGS;
|
||||||
(*ntf_q_pp)->n_arg = m_ptr->NOTIFY_ARG;
|
(*ntf_q_pp)->n_arg = m_ptr->NOTIFY_ARG;
|
||||||
break;
|
return(OK);
|
||||||
}
|
}
|
||||||
return(OK);
|
ntf_q_pp = &(*ntf_q_pp)->n_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add to end of queue. Get a free notification buffer. */
|
/* Add to end of queue. Get a free notification buffer. */
|
||||||
if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0)
|
if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0)
|
||||||
return(ENOSPC); /* should be atomic! */
|
return(ENOSPC);
|
||||||
kinfo.nr_ntf_pending ++;
|
|
||||||
ntf_p = ¬ify_buffer[ntf_index];
|
ntf_p = ¬ify_buffer[ntf_index];
|
||||||
ntf_p->n_source = proc_number(caller_ptr);
|
ntf_p->n_source = proc_nr(caller_ptr);
|
||||||
ntf_p->n_type = m_ptr->NOTIFY_TYPE;
|
ntf_p->n_type = m_ptr->NOTIFY_TYPE;
|
||||||
ntf_p->n_flags = m_ptr->NOTIFY_FLAGS;
|
ntf_p->n_flags = m_ptr->NOTIFY_FLAGS;
|
||||||
ntf_p->n_arg = m_ptr->NOTIFY_ARG;
|
ntf_p->n_arg = m_ptr->NOTIFY_ARG;
|
||||||
*ntf_q_pp = ntf_p;
|
*ntf_q_pp = ntf_p; /* add to end of queue */
|
||||||
|
ntf_p->n_next = NULL; /* mark new end of queue */
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
@ -374,16 +406,13 @@ message *m_ptr; /* pointer to message buffer */
|
||||||
{
|
{
|
||||||
/* Safe gateway to mini_notify() for tasks and interrupt handlers. This
|
/* Safe gateway to mini_notify() for tasks and interrupt handlers. This
|
||||||
* function checks if it is called from an interrupt handler and makes sure
|
* function checks if it is called from an interrupt handler and makes sure
|
||||||
* that the correct message source is put on the notification. All kernel
|
* that the correct message source is put on the notification.
|
||||||
* generated notifications share the same pseudo-process number, to prevent
|
|
||||||
* conflicts with SENDREC calls to the kernel task.
|
|
||||||
*/
|
*/
|
||||||
int result;
|
int result;
|
||||||
struct proc *caller_ptr;
|
struct proc *caller_ptr;
|
||||||
|
|
||||||
lock();
|
lock();
|
||||||
caller_ptr = (k_reenter >= 0 || istaskp(proc_ptr)) ?
|
caller_ptr = (k_reenter >= 0) ? proc_addr(HARDWARE) : proc_ptr;
|
||||||
proc_addr(KERNEL) : proc_ptr;
|
|
||||||
result = mini_notify(caller_ptr, dst, m_ptr);
|
result = mini_notify(caller_ptr, dst, m_ptr);
|
||||||
unlock();
|
unlock();
|
||||||
return(result);
|
return(result);
|
||||||
|
@ -423,6 +452,7 @@ register struct proc *rp; /* this process is now runnable */
|
||||||
{
|
{
|
||||||
/* Add 'rp' to one of the queues of runnable processes. */
|
/* Add 'rp' to one of the queues of runnable processes. */
|
||||||
register int q = rp->p_priority; /* scheduling queue to use */
|
register int q = rp->p_priority; /* scheduling queue to use */
|
||||||
|
register struct proc **xpp; /* iterate over queue */
|
||||||
|
|
||||||
#if ENABLE_K_DEBUGGING
|
#if ENABLE_K_DEBUGGING
|
||||||
if(rp->p_ready) {
|
if(rp->p_ready) {
|
||||||
|
@ -435,6 +465,18 @@ register struct proc *rp; /* this process is now runnable */
|
||||||
* user processes are added in front of the queue, because this is a bit
|
* user processes are added in front of the queue, because this is a bit
|
||||||
* fairer to I/O bound processes.
|
* fairer to I/O bound processes.
|
||||||
*/
|
*/
|
||||||
|
#if NEW_SCHED_Q
|
||||||
|
if (isuserp(rp)) { /* add to front of queue */
|
||||||
|
rp->p_nextready = rdy_head[q]; /* chain current front */
|
||||||
|
rdy_head[q] = rp; /* ready process becomes front */
|
||||||
|
}
|
||||||
|
else { /* add to end of queue */
|
||||||
|
xpp = &rdy_head[q]; /* find pointer to end of queue */
|
||||||
|
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_nextready;
|
||||||
|
*xpp = rp; /* replace end with ready process */
|
||||||
|
rp->p_nextready = NIL_PROC; /* mark end of queue */
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (isuserp(rp)) { /* add to front of queue */
|
if (isuserp(rp)) { /* add to front of queue */
|
||||||
if (rdy_head[q] == NIL_PROC)
|
if (rdy_head[q] == NIL_PROC)
|
||||||
rdy_tail[q] = rp;
|
rdy_tail[q] = rp;
|
||||||
|
@ -449,6 +491,7 @@ register struct proc *rp; /* this process is now runnable */
|
||||||
rdy_tail[q] = rp;
|
rdy_tail[q] = rp;
|
||||||
rp->p_nextready = NIL_PROC;
|
rp->p_nextready = NIL_PROC;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Run 'rp' next if it has a higher priority than 'proc_ptr' or 'next_ptr'.
|
/* Run 'rp' next if it has a higher priority than 'proc_ptr' or 'next_ptr'.
|
||||||
* This actually should be done via pick_proc(), but the message passing
|
* This actually should be done via pick_proc(), but the message passing
|
||||||
|
@ -456,10 +499,6 @@ register struct proc *rp; /* this process is now runnable */
|
||||||
*/
|
*/
|
||||||
if (next_ptr && next_ptr->p_priority > rp->p_priority) next_ptr = rp;
|
if (next_ptr && next_ptr->p_priority > rp->p_priority) next_ptr = rp;
|
||||||
else if (proc_ptr->p_priority > rp->p_priority) next_ptr = rp;
|
else if (proc_ptr->p_priority > rp->p_priority) next_ptr = rp;
|
||||||
|
|
||||||
#if DEAD_CODE
|
|
||||||
if (rp->p_priority < proc_ptr->p_priority) proc_ptr = rp;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -470,9 +509,13 @@ register struct proc *rp; /* this process is no longer runnable */
|
||||||
{
|
{
|
||||||
/* A process has blocked. See ready for a description of the queues. */
|
/* A process has blocked. See ready for a description of the queues. */
|
||||||
|
|
||||||
register struct proc *xp;
|
|
||||||
register struct proc **qtail; /* queue's rdy_tail */
|
|
||||||
register int q = rp->p_priority; /* queue to use */
|
register int q = rp->p_priority; /* queue to use */
|
||||||
|
#if NEW_SCHED_Q
|
||||||
|
register struct proc **xpp; /* iterate over queue */
|
||||||
|
#else
|
||||||
|
register struct proc **qtail; /* queue's rdy_tail */
|
||||||
|
register struct proc *xp;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLE_K_DEBUGGING
|
#if ENABLE_K_DEBUGGING
|
||||||
if(!rp->p_ready) {
|
if(!rp->p_ready) {
|
||||||
|
@ -484,13 +527,25 @@ register struct proc *rp; /* this process is no longer runnable */
|
||||||
/* Side-effect for tasks: check if the task's stack still is ok? */
|
/* Side-effect for tasks: check if the task's stack still is ok? */
|
||||||
if (istaskp(rp)) {
|
if (istaskp(rp)) {
|
||||||
if (*rp->p_stguard != STACK_GUARD)
|
if (*rp->p_stguard != STACK_GUARD)
|
||||||
panic("stack overrun by task", proc_number(rp));
|
panic("stack overrun by task", proc_nr(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now make sure that the process is not in its ready queue. Remove the
|
/* Now make sure that the process is not in its ready queue. Remove the
|
||||||
* process if it is found. A process can be made unready even if it is not
|
* process if it is found. A process can be made unready even if it is not
|
||||||
* running by being sent a signal that kills it.
|
* running by being sent a signal that kills it.
|
||||||
*/
|
*/
|
||||||
|
#if NEW_SCHED_Q
|
||||||
|
xpp = &rdy_head[q];
|
||||||
|
while (*xpp != NIL_PROC) { /* check entire queue */
|
||||||
|
if (*xpp == rp) { /* lookup unready process */
|
||||||
|
*xpp = (*xpp)->p_nextready; /* replace it with next */
|
||||||
|
if (rp == proc_ptr || rp == next_ptr) /* current process removed */
|
||||||
|
pick_proc(); /* pick new process to run */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xpp = &(*xpp)->p_nextready; /* proceed to next */
|
||||||
|
}
|
||||||
|
#else
|
||||||
if ( (xp = rdy_head[q]) != NIL_PROC) { /* ready queue is empty */
|
if ( (xp = rdy_head[q]) != NIL_PROC) { /* ready queue is empty */
|
||||||
if (xp == rp) { /* check head of queue */
|
if (xp == rp) { /* check head of queue */
|
||||||
rdy_head[q] = xp->p_nextready; /* new head of queue */
|
rdy_head[q] = xp->p_nextready; /* new head of queue */
|
||||||
|
@ -508,25 +563,41 @@ register struct proc *rp; /* this process is no longer runnable */
|
||||||
rdy_tail[q] = xp;
|
rdy_tail[q] = xp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* sched *
|
* sched *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void sched()
|
PRIVATE void sched(queue)
|
||||||
|
int queue;
|
||||||
{
|
{
|
||||||
/* The current process has run too long. If another low priority (user)
|
/* The current process has run too long. If another low priority (user)
|
||||||
* process is runnable, put the current process on the end of the user queue,
|
* process is runnable, put the current process on the end of the user queue,
|
||||||
* possibly promoting another user to head of the queue.
|
* possibly promoting another user to head of the queue.
|
||||||
*/
|
*/
|
||||||
if (rdy_head[PPRI_USER] == NIL_PROC) return;
|
register struct proc **xpp;
|
||||||
|
register struct proc *xp;
|
||||||
|
|
||||||
|
if (rdy_head[queue] == NIL_PROC) return;
|
||||||
|
|
||||||
/* One or more user processes queued. */
|
/* One or more user processes queued. */
|
||||||
rdy_tail[PPRI_USER]->p_nextready = rdy_head[PPRI_USER];
|
#if NEW_SCHED_Q
|
||||||
rdy_tail[PPRI_USER] = rdy_head[PPRI_USER];
|
|
||||||
rdy_head[PPRI_USER] = rdy_head[PPRI_USER]->p_nextready;
|
xp = rdy_head[queue]; /* save expired process */
|
||||||
rdy_tail[PPRI_USER]->p_nextready = NIL_PROC;
|
rdy_head[queue] = xp->p_nextready; /* advance to next process */
|
||||||
|
xpp = &rdy_head[queue]; /* find end of queue */
|
||||||
|
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_nextready;
|
||||||
|
*xpp = xp; /* add expired to end */
|
||||||
|
xp->p_nextready = NIL_PROC; /* mark end of queue */
|
||||||
|
|
||||||
|
#else
|
||||||
|
rdy_tail[queue]->p_nextready = rdy_head[queue];
|
||||||
|
rdy_tail[queue] = rdy_head[queue];
|
||||||
|
rdy_head[queue] = rdy_head[queue]->p_nextready;
|
||||||
|
rdy_tail[queue]->p_nextready = NIL_PROC;
|
||||||
|
#endif
|
||||||
pick_proc();
|
pick_proc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,11 +656,12 @@ struct proc *rp; /* this process is no longer runnable */
|
||||||
/*==========================================================================*
|
/*==========================================================================*
|
||||||
* lock_sched *
|
* lock_sched *
|
||||||
*==========================================================================*/
|
*==========================================================================*/
|
||||||
PUBLIC void lock_sched()
|
PUBLIC void lock_sched(queue)
|
||||||
|
int queue;
|
||||||
{
|
{
|
||||||
/* Safe gateway to sched() for tasks. */
|
/* Safe gateway to sched() for tasks. */
|
||||||
lock();
|
lock();
|
||||||
sched();
|
sched(queue);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct proc {
|
||||||
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */
|
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */
|
||||||
struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */
|
struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */
|
||||||
|
|
||||||
short p_flags; /* SENDING, RECEIVING, etc. */
|
char p_flags; /* SENDING, RECEIVING, etc. */
|
||||||
char p_type; /* task, system, driver, server, user, idle */
|
char p_type; /* task, system, driver, server, user, idle */
|
||||||
char p_priority; /* scheduling priority */
|
char p_priority; /* scheduling priority */
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ struct proc {
|
||||||
struct proc *p_nextready; /* pointer to next ready process */
|
struct proc *p_nextready; /* pointer to next ready process */
|
||||||
struct notification *p_ntf_q; /* queue of pending notifications */
|
struct notification *p_ntf_q; /* queue of pending notifications */
|
||||||
struct proc *p_caller_q; /* head of list of procs wishing to send */
|
struct proc *p_caller_q; /* head of list of procs wishing to send */
|
||||||
struct proc *p_sendlink; /* link to next proc wishing to send */
|
struct proc *p_q_link; /* link to next proc wishing to send */
|
||||||
message *p_messbuf; /* pointer to message buffer */
|
message *p_messbuf; /* pointer to message buffer */
|
||||||
proc_nr_t p_getfrom; /* from whom does process want to receive? */
|
proc_nr_t p_getfrom; /* from whom does process want to receive? */
|
||||||
proc_nr_t p_sendto; /* to whom does process want to send? */
|
proc_nr_t p_sendto; /* to whom does process want to send? */
|
||||||
|
@ -74,9 +74,9 @@ struct proc {
|
||||||
#define NO_MAP 0x01 /* keeps unmapped forked child from running */
|
#define NO_MAP 0x01 /* keeps unmapped forked child from running */
|
||||||
#define SENDING 0x02 /* set when process blocked trying to send */
|
#define SENDING 0x02 /* set when process blocked trying to send */
|
||||||
#define RECEIVING 0x04 /* set when process blocked trying to recv */
|
#define RECEIVING 0x04 /* set when process blocked trying to recv */
|
||||||
#define PENDING 0x08 /* set when inform() of signal pending */
|
#define PENDING 0x10 /* set when inform() of signal pending */
|
||||||
#define SIG_PENDING 0x10 /* keeps to-be-signalled proc from running */
|
#define SIG_PENDING 0x20 /* keeps to-be-signalled proc from running */
|
||||||
#define P_STOP 0x20 /* set when process is being traced */
|
#define P_STOP 0x40 /* set when process is being traced */
|
||||||
|
|
||||||
/* Values for p_type. Non-negative values represent active process types.
|
/* Values for p_type. Non-negative values represent active process types.
|
||||||
* Process types are important to model inter-process relationships. When
|
* Process types are important to model inter-process relationships. When
|
||||||
|
@ -120,9 +120,6 @@ struct proc {
|
||||||
#define isalive(n) (proc_addr(n)->p_type > P_NONE)
|
#define isalive(n) (proc_addr(n)->p_type > P_NONE)
|
||||||
#define isalivep(p) ((p)->p_type > P_NONE)
|
#define isalivep(p) ((p)->p_type > P_NONE)
|
||||||
#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE)
|
#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE)
|
||||||
#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK)
|
|
||||||
#define issysentn(n) ((n) == FS_PROC_NR || (n) == PM_PROC_NR)
|
|
||||||
#define issysentp(p) (issysentn((p)->p_nr))
|
|
||||||
#define isreservedp(p) ((p)->p_type == P_RESERVED)
|
#define isreservedp(p) ((p)->p_type == P_RESERVED)
|
||||||
#define isemptyp(p) ((p)->p_type == P_NONE)
|
#define isemptyp(p) ((p)->p_type == P_NONE)
|
||||||
#define istaskp(p) ((p)->p_type == P_TASK)
|
#define istaskp(p) ((p)->p_type == P_TASK)
|
||||||
|
@ -131,12 +128,11 @@ struct proc {
|
||||||
#define isuserp(p) ((p)->p_type == P_USER)
|
#define isuserp(p) ((p)->p_type == P_USER)
|
||||||
#define isuser(n) (proc_addr(n)->p_type == P_USER)
|
#define isuser(n) (proc_addr(n)->p_type == P_USER)
|
||||||
#define isidlep(p) ((p)->p_type == P_IDLE)
|
#define isidlep(p) ((p)->p_type == P_IDLE)
|
||||||
#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)]
|
|
||||||
#define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
|
#define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
|
||||||
#define proc_number(p) ((p)->p_nr)
|
#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)]
|
||||||
#define proc_vir2phys(p, vir) \
|
#define proc_nr(p) ((p)->p_nr)
|
||||||
(((phys_bytes)(p)->p_map[D].mem_phys << CLICK_SHIFT) \
|
#define iskernelp(p) ((p)->p_nr < 0)
|
||||||
+ (vir_bytes) (vir))
|
#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK)
|
||||||
|
|
||||||
/* The process table and pointers to process table slots. The pointers allow
|
/* The process table and pointers to process table slots. The pointers allow
|
||||||
* faster access because now a process entry can be found by indexing the
|
* faster access because now a process entry can be found by indexing the
|
||||||
|
|
|
@ -48,7 +48,7 @@ _PROTOTYPE( int lock_notify, (int dst, message *m_ptr) );
|
||||||
_PROTOTYPE( int lock_send, (int dst, message *m_ptr) );
|
_PROTOTYPE( int lock_send, (int dst, message *m_ptr) );
|
||||||
_PROTOTYPE( void lock_pick_proc, (void) );
|
_PROTOTYPE( void lock_pick_proc, (void) );
|
||||||
_PROTOTYPE( void lock_ready, (struct proc *rp) );
|
_PROTOTYPE( void lock_ready, (struct proc *rp) );
|
||||||
_PROTOTYPE( void lock_sched, (void) );
|
_PROTOTYPE( void lock_sched, (int queue) );
|
||||||
_PROTOTYPE( void lock_unready, (struct proc *rp) );
|
_PROTOTYPE( void lock_unready, (struct proc *rp) );
|
||||||
|
|
||||||
/* start.c */
|
/* start.c */
|
||||||
|
|
|
@ -79,7 +79,7 @@ PUBLIC void sys_task()
|
||||||
if ((unsigned) m.m_type < NR_SYS_CALLS) {
|
if ((unsigned) m.m_type < NR_SYS_CALLS) {
|
||||||
result = (*call_vec[m.m_type])(&m); /* do system call */
|
result = (*call_vec[m.m_type])(&m); /* do system call */
|
||||||
} else {
|
} else {
|
||||||
kprintf("SYS task got illegal request from %d.\n", m.m_source);
|
kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
|
||||||
result = EBADREQUEST; /* illegal message type */
|
result = EBADREQUEST; /* illegal message type */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,8 @@ PUBLIC void sys_task()
|
||||||
*/
|
*/
|
||||||
if (result != EDONTREPLY) {
|
if (result != EDONTREPLY) {
|
||||||
m.m_type = result; /* report status of call */
|
m.m_type = result; /* report status of call */
|
||||||
lock_send(m.m_source, &m);
|
if (OK != lock_send(m.m_source, &m))
|
||||||
|
kprintf("Warning, SYSTASK couldn't reply to %d\n", m.m_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +178,11 @@ PUBLIC void clear_proc(proc_nr)
|
||||||
int proc_nr; /* slot of process to clean up */
|
int proc_nr; /* slot of process to clean up */
|
||||||
{
|
{
|
||||||
register struct proc *rp, *rc;
|
register struct proc *rp, *rc;
|
||||||
|
#if DEAD_CODE
|
||||||
struct proc *np, *xp;
|
struct proc *np, *xp;
|
||||||
|
#else
|
||||||
|
register struct proc **xpp; /* iterate over caller queue */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get a pointer to the process that exited. */
|
/* Get a pointer to the process that exited. */
|
||||||
rc = proc_addr(proc_nr);
|
rc = proc_addr(proc_nr);
|
||||||
|
@ -199,22 +204,34 @@ int proc_nr; /* slot of process to clean up */
|
||||||
/* Check all proc slots to see if the exiting process is queued. */
|
/* Check all proc slots to see if the exiting process is queued. */
|
||||||
for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
|
for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
|
||||||
if (rp->p_caller_q == NIL_PROC) continue;
|
if (rp->p_caller_q == NIL_PROC) continue;
|
||||||
|
#if DEAD_CODE
|
||||||
if (rp->p_caller_q == rc) {
|
if (rp->p_caller_q == rc) {
|
||||||
/* Exiting process is on front of this queue. */
|
/* Exiting process is on front of this queue. */
|
||||||
rp->p_caller_q = rc->p_sendlink;
|
rp->p_caller_q = rc->p_q_link;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* See if exiting process is in middle of queue. */
|
/* See if exiting process is in middle of queue. */
|
||||||
np = rp->p_caller_q;
|
np = rp->p_caller_q;
|
||||||
while ( ( xp = np->p_sendlink) != NIL_PROC) {
|
while ( ( xp = np->p_q_link) != NIL_PROC) {
|
||||||
if (xp == rc) {
|
if (xp == rc) {
|
||||||
np->p_sendlink = xp->p_sendlink;
|
np->p_q_link = xp->p_q_link;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
np = xp;
|
np = xp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* Make sure that the exiting process is not on the queue. */
|
||||||
|
xpp = &rp->p_caller_q;
|
||||||
|
while (*xpp != NIL_PROC) { /* check entire queue */
|
||||||
|
if (*xpp == rc) { /* process is on the queue */
|
||||||
|
*xpp = (*xpp)->p_q_link; /* replace by next process */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,6 @@ timer_t *tp;
|
||||||
* process given with a SYN_ALARM message.
|
* process given with a SYN_ALARM message.
|
||||||
*/
|
*/
|
||||||
message m;
|
message m;
|
||||||
m.NOTIFY_SOURCE = SYSTASK;
|
|
||||||
m.NOTIFY_TYPE = SYN_ALARM;
|
m.NOTIFY_TYPE = SYN_ALARM;
|
||||||
m.NOTIFY_ARG = get_uptime();
|
m.NOTIFY_ARG = get_uptime();
|
||||||
m.NOTIFY_FLAGS = 0;
|
m.NOTIFY_FLAGS = 0;
|
||||||
|
|
|
@ -35,7 +35,7 @@ message *m_ptr; /* pointer to request message */
|
||||||
/* Find the next process with pending signals. */
|
/* Find the next process with pending signals. */
|
||||||
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
|
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
|
||||||
if (rp->p_flags & PENDING) {
|
if (rp->p_flags & PENDING) {
|
||||||
m_ptr->SIG_PROC = proc_number(rp);
|
m_ptr->SIG_PROC = rp->p_nr;
|
||||||
m_ptr->SIG_MAP = rp->p_pending;
|
m_ptr->SIG_MAP = rp->p_pending;
|
||||||
sigemptyset(&rp->p_pending); /* ball is in PM's court */
|
sigemptyset(&rp->p_pending); /* ball is in PM's court */
|
||||||
rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
|
rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
|
||||||
|
|
|
@ -67,11 +67,11 @@ PUBLIC struct system_image image[] = {
|
||||||
{ HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" },
|
{ HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" },
|
||||||
{ PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" },
|
{ PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" },
|
||||||
{ FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" },
|
{ FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" },
|
||||||
{ IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGHER, 0, IS_SENDMASK, "IS" },
|
{ IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, IS_SENDMASK, "IS" },
|
||||||
{ TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" },
|
{ TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" },
|
||||||
{ MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, MEM_SENDMASK, "MEMORY" },
|
{ MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, MEM_SENDMASK, "MEMORY" },
|
||||||
#if ENABLE_AT_WINI
|
#if ENABLE_AT_WINI
|
||||||
{ AT_WINI, 0, P_DRIVER, PPRI_HIGHER, 0, AT_SENDMASK, "AT_WINI" },
|
{ AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, AT_SENDMASK, "AT_WINI" },
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FLOPPY
|
#if ENABLE_FLOPPY
|
||||||
{ FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, FLOPPY_SENDMASK, "FLOPPY" },
|
{ FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, FLOPPY_SENDMASK, "FLOPPY" },
|
||||||
|
|
|
@ -51,8 +51,13 @@ struct system_image image[IMAGE_SIZE];
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int do_fkey_pressed(message *m)
|
PUBLIC int do_fkey_pressed(message *m)
|
||||||
{
|
{
|
||||||
|
#if DEAD_CODE
|
||||||
if (F1 <= m->FKEY_CODE && m->FKEY_CODE <= F12) {
|
if (F1 <= m->FKEY_CODE && m->FKEY_CODE <= F12) {
|
||||||
switch(m->FKEY_CODE) {
|
switch(m->FKEY_CODE) {
|
||||||
|
#else
|
||||||
|
if (F1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= F12) {
|
||||||
|
switch(m->NOTIFY_ARG) {
|
||||||
|
#endif
|
||||||
case F1: proctab_dmp(); break;
|
case F1: proctab_dmp(); break;
|
||||||
case F2: memmap_dmp(); break;
|
case F2: memmap_dmp(); break;
|
||||||
case F3: image_dmp(); break;
|
case F3: image_dmp(); break;
|
||||||
|
@ -65,7 +70,12 @@ PUBLIC int do_fkey_pressed(message *m)
|
||||||
case F11: memchunks_dmp(); break;
|
case F11: memchunks_dmp(); break;
|
||||||
case F12: sched_dmp(); break;
|
case F12: sched_dmp(); break;
|
||||||
default:
|
default:
|
||||||
|
#if DEAD_CODE
|
||||||
printf("IS: unhandled notification for F%d\n", m->FKEY_NUM);
|
printf("IS: unhandled notification for F%d\n", m->FKEY_NUM);
|
||||||
|
#else
|
||||||
|
printf("IS: unhandled notify for F%d (code %d)\n",
|
||||||
|
m->NOTIFY_ARG, m->NOTIFY_FLAGS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(EDONTREPLY);
|
return(EDONTREPLY);
|
||||||
|
@ -376,7 +386,7 @@ PRIVATE void sendmask_dmp()
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
printf(" ");
|
printf(" ");
|
||||||
for (j=proc_number(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) {
|
for (j=proc_nr(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) {
|
||||||
printf("%3d", j);
|
printf("%3d", j);
|
||||||
}
|
}
|
||||||
printf(" *\n");
|
printf(" *\n");
|
||||||
|
@ -386,17 +396,17 @@ PRIVATE void sendmask_dmp()
|
||||||
if (++n > 20) break;
|
if (++n > 20) break;
|
||||||
|
|
||||||
printf("%8s ", rp->p_name);
|
printf("%8s ", rp->p_name);
|
||||||
j = proc_number(rp);
|
j = proc_nr(rp);
|
||||||
switch(rp->p_type) {
|
switch(rp->p_type) {
|
||||||
case P_IDLE: printf("/%3d/ ", proc_number(rp)); break;
|
case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break;
|
||||||
case P_TASK: printf("[%3d] ", proc_number(rp)); break;
|
case P_TASK: printf("[%3d] ", proc_nr(rp)); break;
|
||||||
case P_SYSTEM: printf("<%3d> ", proc_number(rp)); break;
|
case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break;
|
||||||
case P_DRIVER: printf("{%3d} ", proc_number(rp)); break;
|
case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break;
|
||||||
case P_SERVER: printf("(%3d) ", proc_number(rp)); break;
|
case P_SERVER: printf("(%3d) ", proc_nr(rp)); break;
|
||||||
default: printf(" %3d ", proc_number(rp));
|
default: printf(" %3d ", proc_nr(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j=proc_number(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
|
for (j=proc_nr(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
|
||||||
if (isallowed(rp->p_sendmask, j)) printf(" 1 ");
|
if (isallowed(rp->p_sendmask, j)) printf(" 1 ");
|
||||||
else printf(" 0 ");
|
else printf(" 0 ");
|
||||||
}
|
}
|
||||||
|
@ -438,12 +448,12 @@ PRIVATE void proctab_dmp()
|
||||||
size = rp->p_memmap[T].mem_len
|
size = rp->p_memmap[T].mem_len
|
||||||
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
|
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
|
||||||
switch(rp->p_type) {
|
switch(rp->p_type) {
|
||||||
case P_IDLE: printf("/%3d/ ", proc_number(rp)); break;
|
case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break;
|
||||||
case P_TASK: printf("[%3d] ", proc_number(rp)); break;
|
case P_TASK: printf("[%3d] ", proc_nr(rp)); break;
|
||||||
case P_SYSTEM: printf("<%3d> ", proc_number(rp)); break;
|
case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break;
|
||||||
case P_DRIVER: printf("{%3d} ", proc_number(rp)); break;
|
case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break;
|
||||||
case P_SERVER: printf("(%3d) ", proc_number(rp)); break;
|
case P_SERVER: printf("(%3d) ", proc_nr(rp)); break;
|
||||||
default: printf(" %3d ", proc_number(rp));
|
default: printf(" %3d ", proc_nr(rp));
|
||||||
}
|
}
|
||||||
printf("%3u %7lx%7lx %6lu%6lu%6uK%6uK%6uK %3x",
|
printf("%3u %7lx%7lx %6lu%6lu%6uK%6uK%6uK %3x",
|
||||||
rp->p_priority,
|
rp->p_priority,
|
||||||
|
@ -493,7 +503,7 @@ PRIVATE void memmap_dmp()
|
||||||
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
|
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
|
||||||
- rp->p_memmap[D].mem_phys);
|
- rp->p_memmap[D].mem_phys);
|
||||||
printf("%3d %-7.7s %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n",
|
printf("%3d %-7.7s %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n",
|
||||||
proc_number(rp),
|
proc_nr(rp),
|
||||||
rp->p_name,
|
rp->p_name,
|
||||||
rp->p_memmap[T].mem_vir, rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len,
|
rp->p_memmap[T].mem_vir, rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len,
|
||||||
rp->p_memmap[D].mem_vir, rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,
|
rp->p_memmap[D].mem_vir, rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,
|
||||||
|
|
Loading…
Reference in a new issue