Cleaned up process table structure: removed p_type, p_pendcount.

Removed stop sequence when MINIX is shut down.
Disabled send mask checks --- to be replaced by proper mechanism.
Fixed bug relating to 'shutdown -x'.
Simplified clock accounting of realtime.
Updated Makefiles for mkdept script.
This commit is contained in:
Jorrit Herder 2005-06-24 16:24:40 +00:00
parent 5654996c07
commit a408699ce0
19 changed files with 153 additions and 630 deletions

View file

@ -3,12 +3,8 @@
# Directories
u = /usr
i = $u/include
s = $i/sys
h = $i/minix
b = $i/ibm
l = $u/lib
n = $i/net
g = $n/gen
s = system
# Programs, flags, etc.
CC = exec cc
@ -20,16 +16,17 @@ LDFLAGS = -i
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
SYS = system/system.a
SYS_OBJS = $s/proctl.o $s/copying.o $s/devio.o $s/sysctl.o $s/misc.o \
$s/sigctl.o $s/tracing.o $s/clock.o $s/irqctl.o $s/debugging.o
LIBS = -ltimers
# What to make.
kernel build: $(HEAD) $(OBJS) $(SYS)
$(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS) $(LIBS)
kernel build: $(HEAD) $(OBJS) $(SYS_OBJS)
$(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS_OBJS) $(LIBS)
install -S 0 kernel
$(SYS):
$(SYS_OBJS):
cd system && $(MAKE)
all install:
@ -39,110 +36,10 @@ clean:
cd system && $(MAKE) -$(MAKEFLAGS) $@
rm -f *.o *.bak kernel
# Dependencies
a = kernel.h const.h type.h proto.h glo.h \
$h/config.h $h/const.h $h/type.h $h/ipc.h \
$s/types.h \
$i/string.h $i/limits.h $i/errno.h $i/timers.h \
$b/portio.h $b/interrupt.h $b/bios.h $b/ports.h
depend:
cd system && $(MAKE) -$(MAKEFLAGS) $@
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c system/*.c > .depend
klibc.o: $a
klib.o: $h/config.h $h/const.h const.h sconst.h protect.h
klib.o: klib88.s klib386.s
mpx.o: $h/config.h $h/const.h $h/com.h const.h protect.h sconst.h
mpx.o: mpx88.s mpx386.s
mpx.o: mpx88.s mpx386.s
clock.o: $a
clock.o: $i/signal.h
clock.o: $h/callnr.h
clock.o: $h/com.h
clock.o: proc.h
start.o: $a
start.o: $i/stdlib.h
start.o: protect.h
exception.o: $a
exception.o: $i/signal.h
exception.o: $h/com.h
exception.o: proc.h
driver.o: $a $d
driver.o: $h/ioctl.h
driver.o: $s/ioc_disk.h
drvlib.o: $a $d $(dl)
i8259.o: $a
main.o: $a
main.o: $i/unistd.h
main.o: $i/signal.h
main.o: $i/a.out.h
main.o: $h/callnr.h
main.o: $h/com.h
main.o: proc.h
main.o: sendmask.h
misc.o: $a
misc.o: $i/stdlib.h
misc.o: $h/com.h
printer.o: $a
printer.o: $h/callnr.h
printer.o: $h/com.h
printer.o: proc.h
proc.o: $a
proc.o: $h/callnr.h
proc.o: $h/com.h
proc.o: proc.h
proc.o: ipc.h
proc.o: sendmask.h
protect.o: $a
protect.o: $h/com.h
protect.o: proc.h
protect.o: protect.h
system.o: $a
system.o: $i/stdlib.h
system.o: $i/signal.h
system.o: $i/unistd.h
system.o: $s/sigcontext.h
system.o: $s/ptrace.h
system.o: $h/ioctl.h
system.o: $s/svrctl.h
system.o: $h/callnr.h
system.o: $h/com.h
system.o: system.h
system.o: proc.h
system.o: protect.h
system.o: sendmask.h
table.o: $a
table.o: $i/stdlib.h
table.o: $i/termios.h
table.o: $h/com.h
table.o: proc.h
table.o: sendmask.h
table.o: $b/int86.h
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
system/system.a: $i/signal.h $i/unistd.h
system/system.a: system/clock.c
system/system.a: system/copying.c
system/system.a: system/devio.c
system/system.a: system/irqctl.c
system/system.a: system/misc.c
system/system.a: system/proctl.c
system/system.a: system/sigctl.c
system/system.a: system/sysctl.c
system/system.a: system/tracing.c
system/system.a: system/debugging.c
# Include generated dependencies.
include .depend

View file

@ -1,4 +1,3 @@
#define NEW_TIME_COUNT 1
/* The file contais the clock task, which handles all time related functions.
* Important events that are handled by the CLOCK include alarm timers and
* (re)scheduling user processes.
@ -85,9 +84,6 @@ PRIVATE clock_t realtime; /* real time clock */
/* Variables for and changed by the CLOCK's interrupt handler. */
PRIVATE irq_hook_t clock_hook;
#if ! NEW_TIME_COUNT
PRIVATE clock_t pending_ticks; /* ticks seen by low level only */
#endif
PRIVATE int sched_ticks = SCHED_RATE; /* counter: when 0, call scheduler */
PRIVATE struct proc *prev_ptr; /* last user process run by clock */
@ -107,17 +103,10 @@ PUBLIC void clock_task()
/* Main loop of the clock task. Get work, process it, sometimes reply. */
while (TRUE) {
/* Go get a message. */
receive(ANY, &m);
#if ! NEW_TIME_COUNT
/* Transfer ticks seen by the low level handler. */
lock(8, "realtime");
realtime += pending_ticks;
pending_ticks = 0;
unlock(8);
#endif
/* Handle the request. */
switch (m.m_type) {
case HARD_INT:
@ -161,7 +150,7 @@ message *m_ptr; /* pointer to request message */
/* If a process has been running too long, pick another one. */
if (--sched_ticks <= 0) {
if (bill_ptr == prev_ptr)
lock_sched(PPRI_USER); /* process has run too long */
lock_sched(USER_Q); /* process has run too long */
sched_ticks = SCHED_RATE; /* reset quantum */
prev_ptr = bill_ptr; /* new previous process */
}
@ -195,7 +184,7 @@ irq_hook_t *hook;
* is changing them, provided they are always valid pointers,
* since at worst the previous process would be billed.
* next_timeout, realtime, sched_ticks, bill_ptr, prev_ptr
* rdy_head[PPRI_USER]
* rdy_head[USER_Q]
* These are tested to decide whether to call notify(). It
* does not matter if the test is sometimes (rarely) backwards
* due to a race, since this will only delay the high-level
@ -203,12 +192,6 @@ irq_hook_t *hook;
* The variables which are changed require more care:
* rp->p_user_time, rp->p_sys_time:
* These are protected by explicit locks in system.c.
#if ! NEW_TIME_COUNT
* pending_ticks:
* This is protected by explicit locks in clock.c. Don't
* update realtime directly, since there are too many
* references to it to guard conveniently.
#endif
* lost_ticks:
* Clock ticks counted outside the clock task.
* sched_ticks, prev_ptr:
@ -224,9 +207,6 @@ irq_hook_t *hook;
*/
register unsigned ticks;
message m;
#if ! NEW_TIME_COUNT
clock_t now;
#endif
/* Acknowledge the PS/2 clock interrupt. */
if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
@ -236,16 +216,9 @@ irq_hook_t *hook;
* process is running, charge the billable process for system time as well.
* Thus the unbillable process' user time is the billable user's system time.
*/
#if NEW_TIME_COUNT
ticks = lost_ticks + 1;
lost_ticks = 0;
realtime += ticks;
#else
ticks = lost_ticks + 1;
lost_ticks = 0;
pending_ticks += ticks;
now = realtime + pending_ticks;
#endif
/* Update administration. */
proc_ptr->p_user_time += ticks;
@ -254,12 +227,8 @@ irq_hook_t *hook;
/* Check if do_clocktick() must be called. Done for alarms and scheduling.
* If bill_ptr == prev_ptr, there are no ready users so don't need sched().
*/
#if NEW_TIME_COUNT
if (next_timeout <= realtime || (sched_ticks == 1 && bill_ptr == prev_ptr
#else
if (next_timeout <= now || (sched_ticks == 1 && bill_ptr == prev_ptr
#endif
&& rdy_head[PPRI_USER] != NIL_PROC))
&& rdy_head[USER_Q] != NIL_PROC))
{
m.NOTIFY_TYPE = HARD_INT;
lock_notify(CLOCK, &m);
@ -280,16 +249,7 @@ PUBLIC clock_t get_uptime()
/* Get and return the current clock uptime in ticks.
* Be careful about pending_ticks.
*/
#if NEW_TIME_COUNT
return(realtime);
#else
clock_t uptime;
lock(9, "get_uptime");
uptime = realtime + pending_ticks;
unlock(9);
return(uptime);
#endif
}

View file

@ -53,7 +53,7 @@ unsigned vec_nr;
return;
}
if (k_reenter == 0 && ! istaskp(saved_proc)) {
if (k_reenter == 0 && ! iskernelp(saved_proc)) {
cause_sig(proc_nr(saved_proc), ep->signum);
return;
}

View file

@ -12,9 +12,6 @@
/* Variables relating to shutting down MINIX. */
EXTERN char kernel_exception; /* TRUE after system exceptions */
EXTERN char shutting_down; /* TRUE if shutting down */
EXTERN struct proc *shutdown_process; /* process awaiting shutdown of */
EXTERN timer_t shutdown_timer; /* timer for watchdog function */
/* Kernel information structures. This groups vital kernel information. */
EXTERN phys_bytes aout; /* address of a.out headers */
@ -25,7 +22,8 @@ EXTERN struct randomness krandom; /* gather kernel random information */
/* Process scheduling information and the kernel reentry count. */
EXTERN struct proc *proc_ptr; /* pointer to currently running process */
EXTERN struct proc *next_ptr; /* pointer to next process to run */
EXTERN struct proc *next_ptr; /* next process to run after restart() */
EXTERN struct proc *bill_ptr; /* process to bill for clock ticks */
EXTERN char k_reenter; /* kernel reentry count (entry count less 1) */
EXTERN unsigned lost_ticks; /* clock ticks counted outside clock task */

View file

@ -2,21 +2,15 @@
* The routine main() initializes the system and starts the ball rolling by
* setting up the process table, interrupt vectors, and scheduling each task
* to run to initialize itself.
* The routine prepare_shutdown() tries to cleanly shuts down MINIX by running
* the stop_sequence() to notify all system services and allowing them some
* time to finalize. In case of an exception(), the stop sequence is skipped.
* The routine shutdown() does the opposite and brings down MINIX.
*
* The entries into this file are:
* main: MINIX main program
* prepare_shutdown: prepare to take MINIX down
* stop_sequence: take down all system services
*
* Changes:
* Nov 24, 2004 simplified main() with system image (Jorrit N. Herder)
* Oct 21, 2004 moved copyright to announce() (Jorrit N. Herder)
* Sep 04, 2004 created stop_sequence() to cleanup (Jorrit N. Herder)
* Aug 20, 2004 split wreboot() and shutdown() (Jorrit N. Herder)
* Jun 15, 2004 moved wreboot() to this file (Jorrit N. Herder)
* Aug 20, 2004 new prepare_shutdown() and shutdown() (Jorrit N. Herder)
*/
#include "kernel.h"
#include <signal.h>
@ -31,7 +25,6 @@
FORWARD _PROTOTYPE( void announce, (void));
FORWARD _PROTOTYPE( void shutdown, (timer_t *tp));
#define STOP_TICKS (5*HZ) /* time allowed to stop */
/*===========================================================================*
* main *
@ -52,11 +45,11 @@ PUBLIC void main()
/* Initialize the interrupt controller. */
intr_init(1);
/* Clear the process table. Anounce each slot as empty and
* set up mappings for proc_addr() and proc_nr() macros.
/* Clear the process table. Anounce each slot as empty and set up mappings
* for proc_addr() and proc_nr() macros.
*/
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_flags = SLOT_FREE; /* initialize free slot */
rp->p_nr = i; /* proc number from ptr */
(pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
}
@ -77,7 +70,6 @@ PUBLIC void main()
rp = proc_addr(ttp->proc_nr); /* t's process slot */
kstrncpy(rp->p_name, ttp->proc_name, P_NAME_LEN); /* set name */
rp->p_name[P_NAME_LEN-1] = '\0'; /* just for safety */
rp->p_type = ttp->type; /* type of process */
rp->p_priority = ttp->priority; /* scheduling priority */
rp->p_call_mask = ttp->call_mask; /* allowed system calls */
rp->p_sendmask = ttp->sendmask; /* sendmask protection */
@ -117,7 +109,7 @@ PUBLIC void main()
* access I/O; this is not allowed to less-privileged processes
*/
rp->p_reg.pc = (reg_t) ttp->initial_pc;
rp->p_reg.psw = (isidlep(rp)||istaskp(rp)) ? INIT_TASK_PSW : INIT_PSW;
rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;
/* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc".
@ -176,11 +168,6 @@ PRIVATE void announce(void)
kprintf("Executing in %s mode\n\n",
machine.protected ? karg("32-bit protected") : karg("real"));
#endif
/* Check if boot device was loaded with the kernel. */
if (kinfo.bootdev_base > 0)
kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size);
}
@ -188,15 +175,13 @@ PRIVATE void announce(void)
* prepare_shutdown *
*==========================================================================*/
PUBLIC void prepare_shutdown(how)
int how; /* 0 = halt, 1 = reboot, 2 = panic!, ... */
int how; /* reason to shut down */
{
/* This function prepares to shutdown MINIX. It uses a global flag to make
* sure it is only executed once. Unless a CPU exception occurred, the
* stop_sequence() is started.
*/
static timer_t shutdown_timer; /* timer for watchdog function */
message m;
if (shutting_down)
return;
/* Show debugging dumps on panics. Make sure that the TTY task is still
* available to handle them. This is done with help of a non-blocking send.
@ -214,74 +199,20 @@ int how; /* 0 = halt, 1 = reboot, 2 = panic!, ... */
m.NOTIFY_TYPE = HARD_STOP;
lock_notify(TTY, &m);
/* Run the stop sequence. The timer argument passes the shutdown status.
* The stop sequence is skipped for fatal CPU exceptions.
/* Allow processes to be scheduled to clean up, unless a CPU exception
* occurred. This is done by setting a timer. The timer argument passes
* the shutdown status.
*/
shutting_down = TRUE; /* flag for sys_exit() */
tmr_arg(&shutdown_timer)->ta_int = how; /* pass how in timer */
if (kernel_exception) { /* set in exception() */
kprintf("\nAn exception occured; skipping stop sequence.\n", NO_NUM);
shutdown(&shutdown_timer); /* TTY isn't scheduled */
} else {
kprintf("\nNotifying system services about MINIX shutdown.\n", NO_NUM);
set_timer(&shutdown_timer, get_uptime(), stop_sequence);
set_timer(&shutdown_timer, get_uptime(), shutdown);
}
}
/*==========================================================================*
* stop_sequence *
*==========================================================================*/
PUBLIC void stop_sequence(tp)
timer_t *tp;
{
/* Try to cleanly stop all system services before shutting down. For each
* process type, all processes are notified and given STOP_TICKS to cleanly
* shutdown. The notification order is servers, drivers, tasks. The variable
* 'shutdown_process' is set globally to indicate the process next to stop
* so that the stop sequence can directly continue if it has exited. Only if
* stop sequence has finished, MINIX is brought down.
*/
static int level = P_SERVER; /* start at the highest level */
static struct proc *p = NIL_PROC; /* next process to stop */
static message m;
/* See if the last process' shutdown was successful. Else, force exit. */
if (p != NIL_PROC) {
kprintf("[%s]\n", isalivep(p) ? karg("FAILED") : karg("OK"));
if (isalivep(p))
clear_proc(p->p_nr); /* now force process to exit */
}
/* Find the next process that must be stopped. Continue where last search
* ended or start at begin. Possibly go to next level while searching. If
* the last level is completely searched, shutdown MINIX. Processes are
* stopped in the order of dependencies, that is, from the highest level to
* the lowest level so that, for example, the file system can still rely on
* device drivers to cleanly shutdown.
*/
if (p == NIL_PROC) p = BEG_PROC_ADDR;
while (TRUE) {
if (isalivep(p) && p->p_type == level) { /* found a process */
kprintf("- Stopping %s ... ", karg(p->p_name));
shutdown_process = p; /* directly continue if exited */
m.NOTIFY_TYPE = HARD_STOP;
m.NOTIFY_ARG = tmr_arg(tp)->ta_int; /* how */
lock_notify(proc_nr(p), &m);
set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence);
return; /* allow the process to shut down */
}
p++; /* proceed to next process */
if (p >= END_PROC_ADDR) { /* proceed to next level */
p = BEG_PROC_ADDR;
level = level - 1;
if (level == P_TASK) { /* done; tasks must remain alive */
shutdown(tp);
/* no return */
return;
}
}
}
}
/*==========================================================================*
* shutdown *
@ -290,11 +221,11 @@ PRIVATE void shutdown(tp)
timer_t *tp;
{
/* This function is called from prepare_shutdown or stop_sequence to bring
* down MINIX. How to shutdown is in the argument: RBT_REBOOT, RBT_HALT,
* RBT_RESET.
* down MINIX. How to shutdown is in the argument: RBT_HALT (return to the
* monitor), RBT_MONITOR (execute given code), RBT_RESET (hard reset).
*/
static u16_t magic = STOP_MEM_CHECK;
int how = tmr_arg(tp)->ta_int;
u16_t magic;
/* Now mask all interrupts, including the clock, and stop the clock. */
outb(INT_CTLMASK, ~0);
@ -306,22 +237,17 @@ timer_t *tp;
outb(INT_CTLMASK, 0);
outb(INT2_CTLMASK, 0);
/* Return to the boot monitor. Set the program for the boot monitor.
* For RBT_MONITOR, the MM has provided the program.
*/
if (how == RBT_REBOOT)
phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
else
phys_copy(vir2phys("delay"), kinfo.params_base, 6);
/* Return to the boot monitor. Set the program if not already done. */
if (how != RBT_MONITOR) phys_copy(vir2phys(""), kinfo.params_base, 1);
level0(monitor);
}
/* Stop BIOS memory test. */
phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
/* Reset the system by jumping to the reset address (real mode), or by
* forcing a processor shutdown (protected mode).
* forcing a processor shutdown (protected mode). First stop the BIOS
* memory test by setting a soft reset flag.
*/
magic = STOP_MEM_CHECK;
phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE);
level0(reset);
}

View file

@ -146,17 +146,20 @@ message *m_ptr; /* pointer to message in the caller's space */
case SENDREC: /* has FRESH_ANSWER flag */
/* fall through */
case SEND:
if (! isalive(src_dst)) {
if (isemptyp(proc_addr(src_dst))) {
result = EDEADDST; /* cannot send to the dead */
break;
}
mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst;
#if DEAD_CODE /* to be replaced by better mechanism */
mask_entry = isuserp(proc_addr(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;
}
#endif
result = mini_send(caller_ptr, src_dst, m_ptr, flags);
if (function == SEND || result != OK) {
@ -337,7 +340,7 @@ message *m_ptr; /* pointer to message buffer */
/* Destination is not ready. Add the notification to the pending queue.
* Get pointer to notification message. Don't copy if already in kernel.
*/
if (! istaskp(caller_ptr)) {
if (! iskernelp(caller_ptr)) {
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
proc_addr(HARDWARE), &ntf_mess);
m_ptr = &ntf_mess;
@ -489,8 +492,8 @@ register struct proc *rp; /* this process is no longer runnable */
rp->p_ready = 0;
#endif
/* Side-effect for tasks: check if the task's stack still is ok? */
if (istaskp(rp)) {
/* Side-effect for kernel: check if the task's stack still is ok? */
if (iskernelp(rp)) {
if (*rp->p_stguard != STACK_GUARD)
panic("stack overrun by task", proc_nr(rp));
}

View file

@ -1,17 +1,13 @@
#ifndef PROC_H
#define PROC_H
/* Here is the declaration of the process table. It contains the process'
* registers, memory map, accounting, and message send/receive information.
/* Here is the declaration of the process table. It contains all process
* data, including registers, flags, scheduling priority, memory map,
* accounting, message passing (IPC) information, and so on.
*
* Many assembly code routines reference fields in it. The offsets to these
* fields are defined in the assembler include file sconst.h. When changing
* 'proc', be sure to change sconst.h to match.
*
* Changes:
* May 24, 2005 new field for pending notifications (Jorrit N. Herder)
* Nov 10, 2004 separated process types/ priorities (Jorrit N. Herder)
* Sep 24, 2004 one timer per type of alarm (Jorrit N. Herder)
* May 01, 2004 new p_sendmask to protect syscalls (Jorrit N. Herder)
* struct proc, be sure to change sconst.h to match.
*/
#include <minix/com.h>
#include "protect.h"
@ -23,23 +19,25 @@ struct proc {
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt with ldt base and limit */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
#endif /* (CHIP == INTEL) */
#endif
#if (CHIP == M68000)
/* M68000 specific registers and FPU details go here. */
#endif /* (CHIP == M68000) */
#endif
reg_t *p_stguard; /* stack guard word */
proc_nr_t p_nr; /* number of this process (for fast access) */
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 */
char p_flags; /* SENDING, RECEIVING, etc. */
char p_type; /* task, system, driver, server, user, idle */
char p_priority; /* scheduling priority */
char p_call_mask; /* bit map with allowed system call traps */
char p_priority; /* current scheduling priority */
char p_max_priority; /* maximum (default) scheduling priority */
char p_used_quantums; /* number of full quantums used in a row */
char p_allowed_quantums; /* maximum quantums allowed in a row */
char p_call_mask; /* bit map with allowed system call traps */
send_mask_t p_sendmask; /* mask indicating to whom proc may send */
clock_t p_user_time; /* user time in ticks */
@ -55,7 +53,6 @@ struct proc {
timer_t p_alarm_timer; /* timer shared by different alarm types */
sigset_t p_pending; /* bit map for pending kernel signals */
unsigned p_pendcount; /* count of pending and unfinished signals */
char p_name[P_NAME_LEN]; /* name of the process, including \0 */
@ -67,42 +64,25 @@ struct proc {
/* Guard word for task stacks. */
#define STACK_GUARD ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
/* Bits for p_flags in proc[]. A process is runnable iff p_flags == 0. */
#define NO_MAP 0x01 /* keeps unmapped forked child from running */
#define SENDING 0x02 /* process blocked trying to SEND */
#define RECEIVING 0x04 /* process blocked trying to RECEIVE */
#define PENDING 0x10 /* set when inform() of signal pending */
#define SIG_PENDING 0x20 /* keeps to-be-signalled proc from running */
/* Bits for the process flags. A process is runnable iff p_flags == 0. */
#define SLOT_FREE 0x01 /* process slot is free */
#define NO_MAP 0x02 /* keeps unmapped forked child from running */
#define SENDING 0x04 /* process blocked trying to SEND */
#define RECEIVING 0x08 /* process blocked trying to RECEIVE */
#define SIGNALED 0x10 /* set when new kernel signal arrives */
#define SIG_PENDING 0x20 /* unready while signal being processed */
#define P_STOP 0x40 /* set when process is being traced */
/* Values for p_type. Non-negative values represent active process types.
* Process types are important to model inter-process relationships. When
* MINIX is shutdown, all system services are notified in order of possible
* dependencies, so that, e.g., the FS can rely on drivers to synchronize.
*/
#define P_RESERVED -2 /* slot is not in use, but reserved */
#define P_NONE -1 /* slot is not in use, and free */
#define P_TASK 0 /* kernel process */
#define P_SYSTEM 1 /* low-level system service */
#define P_DRIVER 2 /* device driver */
#define P_SERVER 3 /* system service outside the kernel */
#define P_USER 4 /* user process */
#define P_IDLE 5 /* idle process */
/* Scheduling priorities for p_priority. Values must start at zero and
* increment. Priorities of system services can be set in the task table.
* Task, user, and idle priorities are fixed; the rest can be selected.
/* Scheduling priorities for p_priority. Values must start at zero (highest
* priority) and increment. Priorities of the processes in the boot image can
* be set in table.c.
*/
#define PPRI_TASK 0 /* reserved for kernel tasks */
#define PPRI_HIGHER 1
#define PPRI_HIGH 2
#define PPRI_NORMAL 3
#define PPRI_LOW 4
#define PPRI_LOWER 5
#define PPRI_USER 6 /* reserved for user processes */
#define PPRI_IDLE 7 /* only IDLE process goes here */
#define NR_SCHED_QUEUES 8 /* MUST equal minimum priority + 1 */
#define TASK_Q 0 /* highest, reserved for kernel tasks */
#define USER_Q 4 /* default priority for user processes */
#define IDLE_Q 7 /* lowest, only IDLE process goes here */
#define NR_SCHED_QUEUES 8 /* MUST equal minimum priority + 1 */
/* Magic process table addresses. */
#define BEG_PROC_ADDR (&proc[0])
@ -115,19 +95,13 @@ struct proc {
#define proc_nr(p) ((p)->p_nr)
#define iskerneltask(n) ((n) == CLOCK || (n) == SYSTASK)
#define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE)
#define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
#define isokprocp(p) ((p) >= BEG_PROC_ADDR && (p) < END_PROC_ADDR)
#define isalive(n) (proc_addr(n)->p_type > P_NONE)
#define isalivep(p) ((p)->p_type > P_NONE)
#define isemptyp(p) ((p)->p_type == P_NONE)
#define istaskp(p) ((p)->p_type == P_TASK)
#define isdriverp(p) ((p)->p_type == P_DRIVER)
#define isserverp(p) ((p)->p_type == P_SERVER)
#define isuserp(p) ((p)->p_type == P_USER)
#define isidlep(p) ((p)->p_type == P_IDLE)
#define isuser(n) (proc_addr(n)->p_type == P_USER)
#define iskernelp(p) ((p)->p_nr < 0)
#define isuserp(p) ((p)->p_nr >= 0)
#define isidlep(p) ((p)->p_nr == IDLE)
#define isemptyp(p) ((p)->p_flags == SLOT_FREE)
/* 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
@ -136,7 +110,6 @@ struct proc {
*/
EXTERN struct proc proc[NR_TASKS + NR_PROCS]; /* process table */
EXTERN struct proc *pproc_addr[NR_TASKS + NR_PROCS];
EXTERN struct proc *bill_ptr; /* ptr to process to bill for clock ticks */
EXTERN struct proc *rdy_head[NR_SCHED_QUEUES]; /* ptrs to ready list headers */
EXTERN struct proc *rdy_tail[NR_SCHED_QUEUES]; /* ptrs to ready list tails */

View file

@ -358,8 +358,7 @@ register struct proc *rp;
code_bytes = data_bytes; /* common I&D, poor protect */
else
code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT;
privilege = (isidlep(rp) || istaskp(rp)) ?
TASK_PRIVILEGE : USER_PRIVILEGE;
privilege = (iskernelp(rp)) ? TASK_PRIVILEGE : USER_PRIVILEGE;
init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
(phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT,
code_bytes, privilege);

View file

@ -29,8 +29,6 @@
* Note the one always must start with a default mask like allow_all_mask.
* From that point, one can, for example, deny several processes.
*/
#define allow_all_mask ALLOW_ALL_MASK
#define deny_all_mask DENY_ALL_MASK
#define allow(enabled,n) | (enabled << ((n) + NR_TASKS))
#define deny(enabled,n) & ~(enabled << ((n) + NR_TASKS))
#define send_mask_allow(mask,n) ((mask) |= (1 << ((n) + NR_TASKS)))
@ -39,131 +37,8 @@
/* Check if the bit for the given process number is set. */
#define isallowed(mask,n) ((mask) & (BIT_0 << ((n) + NR_TASKS)))
/* The masks below match the processes (and order) in src/kernel/table.c.
* Note that the masks are made effective the inclusion in the task table
* which is used to set up the process table on start up.
*/
#define TTY_SENDMASK \
allow_all_mask
#define DP8390_SENDMASK \
allow_all_mask
#define RTL8139_SENDMASK \
allow_all_mask
#define IDLE_SENDMASK \
deny_all_mask
/* The tasktab in src/kernel/table.c supports up to 4 controllers
* it is possible to define separate masks for them here, but then
* a small update in table.c is required to make them effective
*/
#define CTRLR_SENDMASK \
allow_all_mask
#define SB16DSP_SENDMASK \
allow_all_mask
#define SB16MIX_SENDMASK \
allow_all_mask
#define FLOPPY_SENDMASK \
allow_all_mask
#define CLOCK_SENDMASK \
allow_all_mask
#define SYSTEM_SENDMASK \
allow_all_mask
#define HARDWARE_SENDMASK \
allow_all_mask \
deny(1, USER_PROC_NR)
#define PM_SENDMASK \
deny_all_mask \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, SYSTASK) \
allow(1, TTY) \
allow(1, MEMORY) \
allow(1, CLOCK) \
allow(1, INIT_PROC_NR) \
allow(1, FS_PROC_NR) \
allow(1, USR8139) \
allow(1, USER_PROC_NR) /* reply to system calls */
#define AT_SENDMASK \
allow_all_mask
#define FS_SENDMASK \
allow_all_mask
#if 0
deny_all_mask \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, SYSTASK) /* need system functionality */ \
allow(1, CLOCK) /* need clock functionality */ \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, TTY) /* a.o. observe function keys */ \
allow(1, FLOPPY) \
allow(ENABLE_SB16, SB16DSP ) \
allow(ENABLE_SB16, SB16MIX ) \
allow(ENABLE_PRINTER, PRINTER ) \
allow(1, MEMORY ) \
allow((NR_CTRLRS >= 1), CTRLR(0)) \
allow((NR_CTRLRS >= 2), CTRLR(1)) \
allow((NR_CTRLRS >= 3), CTRLR(2)) \
allow((NR_CTRLRS >= 4), CTRLR(3)) \
allow(1, INIT_PROC_NR) \
allow(1, PM_PROC_NR) /* cooperates with process manager */ \
allow(1, USER_PROC_NR) /* reply to system calls */
#endif
#define IS_SENDMASK \
allow_all_mask /* IS handles all diagnostic messages */
#if 0
deny_all_mask \
allow(1, CLOCK) /* clock delays and flag alarm needed */ \
allow(1, FS_PROC_NR) /* open /dev/mem to read CMOS clock */ \
allow(1, SYSTASK) /* copy tables from kernel space */ \
allow(1, TTY) /* request function key notifications */ \
allow(1, USER_PROC_NR) /* reply to system calls */
#endif
#define MEM_SENDMASK \
deny_all_mask \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, SYSTASK) /* system functionality needed */ \
allow(1, CLOCK) /* check clock alarms */ \
allow(1, TTY) /* output diagnostics */ \
allow(1, PM_PROC_NR) /* PM alloc mem */ \
allow(1, FS_PROC_NR) /* FS is interface to the driver */
#define PRN_SENDMASK \
deny_all_mask \
allow(1, IS_PROC_NR) /* output diagnostics */ \
allow(1, SYSTASK) /* device port I/O needed */ \
allow(1, TTY) /* output diagnostics */ \
allow(1, CLOCK) /* need small delays */ \
allow(1, FS_PROC_NR) /* FS is interface to the driver */
#define FXP_SENDMASK \
allow_all_mask
#define INIT_SENDMASK \
deny_all_mask \
allow(1, FS_PROC_NR) /* init makes system calls to FS and MM */ \
allow(1, PM_PROC_NR)
#define USER_PROC_SENDMASK \
deny_all_mask \
allow(1, FS_PROC_NR) /* users can only make system calls */ \
allow(1, PM_PROC_NR) \
allow(1, IS_PROC_NR) \
allow(ENABLE_TASKSERVER, TS_PROC_NR)
DENY_ALL_MASK allow(1, PM_PROC_NR) allow(1, FS_PROC_NR)
#endif /* SENDMASK_H */

View file

@ -47,7 +47,7 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
/* Initialize protected mode descriptors. */
prot_init();
/* Copy the boot parameters to kernel memory. */
/* Copy the boot parameters to the local buffer. */
kinfo.params_base = seg2phys(mds) + parmoff;
kinfo.params_size = MIN(parmsize,sizeof(params)-2);
phys_copy(kinfo.params_base, vir2phys(params), kinfo.params_size);

View file

@ -55,7 +55,7 @@ PUBLIC int (*call_vec[NR_SYS_CALLS])(message *m_ptr);
#define map(call_nr, handler) \
{extern int dummy[NR_SYS_CALLS > (unsigned) (call_nr) ? 1 : -1];} \
call_vec[(call_nr)] = (handler)
call_vec[(call_nr)] = (handler)
FORWARD _PROTOTYPE( void initialize, (void));
@ -67,7 +67,7 @@ PUBLIC void sys_task()
{
/* Main entry point of sys_task. Get the message and dispatch on type. */
static message m;
register int result, debug;
register int result;
/* Initialize the system task. */
initialize();
@ -89,11 +89,10 @@ PUBLIC void sys_task()
* is known to be blocked waiting for a message.
*/
if (result != EDONTREPLY) {
debug = m.m_type;
m.m_type = result; /* report status of call */
if (OK != lock_send(m.m_source, &m)) {
kprintf("Warning, SYSTASK couldn't reply to request %d", debug);
kprintf(" from %d\n", m.m_source);
kprintf("Warning, SYSTASK couldn't reply to request from %d\n",
m.m_source);
}
}
}
@ -156,7 +155,6 @@ PRIVATE void initialize(void)
map(SYS_SEGCTL, do_segctl); /* add segment and get selector */
map(SYS_IOPENABLE, do_iopenable); /* enable CPU I/O protection bits */
map(SYS_SVRCTL, do_svrctl); /* kernel control functions */
map(SYS_EXIT, do_exit); /* exit a system process*/
/* Copying. */
map(SYS_UMAP, do_umap); /* map virtual to physical address */
@ -178,11 +176,7 @@ PUBLIC void clear_proc(proc_nr)
int proc_nr; /* slot of process to clean up */
{
register struct proc *rp, *rc;
#if DEAD_CODE
struct proc *np, *xp;
#else
register struct proc **xpp; /* iterate over caller queue */
#endif
int i;
/* Get a pointer to the process that exited. */
@ -203,24 +197,6 @@ int proc_nr; /* slot of process to clean up */
/* Check all proc slots to see if the exiting process is queued. */
for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
if (rp->p_caller_q == NIL_PROC) continue;
#if DEAD_CODE
if (rp->p_caller_q == rc) {
/* Exiting process is on front of this queue. */
rp->p_caller_q = rc->p_q_link;
break;
} else {
/* See if exiting process is in middle of queue. */
np = rp->p_caller_q;
while ( ( xp = np->p_q_link) != NIL_PROC) {
if (xp == rc) {
np->p_q_link = xp->p_q_link;
break;
} else {
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 */
@ -230,7 +206,6 @@ int proc_nr; /* slot of process to clean up */
}
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
}
#endif
}
}
@ -250,9 +225,7 @@ int proc_nr; /* slot of process to clean up */
/* Now clean up the process table entry. Reset to defaults. */
kstrncpy(rc->p_name, "<none>", P_NAME_LEN); /* unset name */
sigemptyset(&rc->p_pending); /* remove pending signals */
rc->p_pendcount = 0; /* all signals are gone */
rc->p_flags = 0; /* remove all flags */
rc->p_type = P_NONE; /* announce slot empty */
rc->p_flags = SLOT_FREE; /* announce slot empty */
rc->p_sendmask = DENY_ALL_MASK; /* set most restrictive mask */
#if (CHIP == M68000)
@ -315,27 +288,25 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
* Signals are handled by sending a message to PM. This function handles the
* signals and makes sure the PM gets them by sending a notification. The
* process being signaled is blocked while PM has not finished all signals
* for it. These signals are counted in p_pendcount, and the SIG_PENDING
* flag is kept nonzero while there are some. It is not sufficient to ready
* the process when PM is informed, because PM can block waiting for FS to
* do a core dump.
* for it.
* It is not sufficient to ready the process when PM is informed, because
* PM can block waiting for FS to do a core dump.
*/
register struct proc *rp;
message m;
/* Check if the signal is already pending. Process it otherwise. */
rp = proc_addr(proc_nr);
if (sigismember(&rp->p_pending, sig_nr))
return; /* this signal already pending */
sigaddset(&rp->p_pending, sig_nr);
++rp->p_pendcount; /* count new signal pending */
if (rp->p_flags & PENDING)
return; /* another signal already pending */
if (rp->p_flags == 0) lock_unready(rp);
rp->p_flags |= PENDING | SIG_PENDING;
m.NOTIFY_TYPE = KSIG_PENDING;
m.NOTIFY_ARG = 0;
m.NOTIFY_FLAGS = 0;
lock_notify(PM_PROC_NR, &m);
if (! sigismember(&rp->p_pending, sig_nr)) {
sigaddset(&rp->p_pending, sig_nr);
if (rp->p_flags & SIGNALED) return; /* other signal pending */
if (rp->p_flags == 0) lock_unready(rp); /* unready if not yet done */
rp->p_flags |= SIGNALED | SIG_PENDING; /* update signal flags */
m.NOTIFY_TYPE = KSIG_PENDING;
m.NOTIFY_ARG = 0;
m.NOTIFY_FLAGS = 0;
lock_notify(PM_PROC_NR, &m);
}
}
@ -355,7 +326,7 @@ vir_bytes bytes; /* # of bytes to be copied */
*/
/* Check all acceptable ranges. */
#if DEAD_CODE
#if DEAD_CODE /* to be replaced by proper ranges, e.g. 640 - 1 KB */
if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END)
return (phys_bytes) vir_addr;
else if (vir_addr >= UPPER_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)

View file

@ -32,8 +32,7 @@ _PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
_PROTOTYPE( int do_abort, (message *m_ptr) );
_PROTOTYPE( int do_getinfo, (message *m_ptr) );
_PROTOTYPE( int do_exit, (message *m_ptr) ); /* system control */
_PROTOTYPE( int do_svrctl, (message *m_ptr) );
_PROTOTYPE( int do_svrctl, (message *m_ptr) ); /* system control */
_PROTOTYPE( int do_iopenable, (message *m_ptr) );
_PROTOTYPE( int do_segctl, (message *m_ptr) );

View file

@ -3,14 +3,6 @@
# Directories
u = /usr
i = $u/include
s = $i/sys
h = $i/minix
m = $i/ibm
l = $u/lib
n = $i/net
g = $n/gen
x = .
k = ..
# Programs, flags, etc.
CC = exec cc
@ -20,35 +12,19 @@ CFLAGS = -I$i
LDFLAGS = -i
SYS = clock.o copying.o debugging.o devio.o irqctl.o proctl.o \
sysctl.o misc.o sigctl.o tracing.o \
sysctl.o misc.o sigctl.o tracing.o
# What to make.
all build: $(SYS)
aal cr system.a $(SYS)
clean:
rm -f *.a *.o *.bak
# Dependencies from src/kernel/kernel.h
a = $h/config.h $h/const.h $h/type.h $h/ipc.h \
$i/string.h $i/limits.h $i/errno.h $i/stddef.h \
$s/types.h \
$m/portio.h \
$k/proc.h $k/const.h $k/type.h $k/proto.h $k/glo.h
depend:
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
# Dependencies from src/kernel/system.h
b = $k/system.h $h/com.h $k/proc.h
clock.o: $a $b
copying.o: $a $b
debugging.o: $a $b
devio.o: $a $b $h/devio.h
irqctl.o: $a $b
misc.o: $a $b $i/unistd.h
proctl.o: $a $b $k/sendmask.h $k/protect.h $i/signal.h
sigctl.o: $a $b $i/signal.h $s/sigcontext.h
sysctl.o: $a $b $s/svrctl.h $k/sendmask.h
tracing.o: $a $b $s/ptrace.h
# Include generated dependencies.
include .depend

View file

@ -157,7 +157,7 @@ check_runqueues(char *when)
}
for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
if(isalivep(xp) && xp->p_ready && !xp->p_found) {
if(! isempty(xp) && xp->p_ready && ! xp->p_found) {
kprintf("scheduling error: ready not on queue: %s\n", (karg_t) when);
panic("ready proc not on scheduling queue", NO_NUM);
if(l++ > PROCLIMIT) { panic("loop in proc.t?", NO_NUM); }

View file

@ -39,7 +39,7 @@ message *m_ptr; /* pointer to request message */
int how = m_ptr->ABRT_HOW;
if (how == RBT_MONITOR) {
/* The monitor is to run user specified instructions. */
/* The monitor is to run the specified instructions. */
int proc_nr = m_ptr->ABRT_MON_PROC;
int length = m_ptr->ABRT_MON_LEN + 1;
vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR;
@ -47,7 +47,7 @@ message *m_ptr; /* pointer to request message */
/* Validate length and address of shutdown code before copying. */
if (length > kinfo.params_size || src_phys == 0)
kprintf("Warning, skipping shutdown code\n", NO_NUM);
phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
else
phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
}

View file

@ -47,15 +47,13 @@ register message *m_ptr; /* pointer to request message */
#endif
rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */
rpc->p_ntf_q = NULL; /* remove pending notifications */
/* Only one in group should have SIGNALED, child doesn't inherit tracing. */
rpc->p_flags |= NO_MAP; /* inhibit process from running */
rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
/* Only 1 in group should have PENDING, child does not inherit trace status*/
rpc->p_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
sigemptyset(&rpc->p_pending);
rpc->p_pendcount = 0;
rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
rpc->p_user_time = 0; /* set all the accounting times to 0 */
rpc->p_sys_time = 0;
@ -175,7 +173,6 @@ register message *m_ptr; /* pointer to request message */
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (slot number of exiting process)
* m1_i2: PR_PPROC_NR (slot number of parent process)
*/
@ -186,36 +183,27 @@ register message *m_ptr; /* pointer to request message */
PUBLIC int do_xit(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_exit. A user process has exited (the PM sent the request).
/* Handle sys_exit. A user process has exited or a system process requests
* to exit. Only the PM can request other process slots to be cleared.
* The routine to clean up a process table slot cancels outstanding timers,
* possibly removes the process from the message queues, and resets certain
* process table fields to the default values.
*/
register struct proc *rc;
int exit_proc_nr;
/* Get a pointer to the process that exited. */
exit_proc_nr = m_ptr->PR_PROC_NR;
if (exit_proc_nr == SELF) exit_proc_nr = m_ptr->m_source;
if (! isokprocn(exit_proc_nr)) return(EINVAL);
rc = proc_addr(exit_proc_nr);
/* Determine what process exited. */
if (PM_PROC_NR == m_ptr->m_source) {
exit_proc_nr = m_ptr->PR_PROC_NR; /* get exiting process */
if (exit_proc_nr != SELF) { /* PM tries to exit self */
if (! isokprocn(exit_proc_nr)) return(EINVAL);
clear_proc(exit_proc_nr); /* exit a user process */
return(OK); /* report back to PM */
}
}
#if DEAD_CODE
/* If this is a user process and the PM passed in a valid parent process,
* accumulate the child times at the parent.
*/
if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
rp = proc_addr(m_ptr->PR_PPROC_NR);
lock(15, "do_xit");
rp->child_utime += rc->user_time + rc->child_utime;
rp->child_stime += rc->sys_time + rc->child_stime;
unlock(15);
}
#endif
/* Now call the routine to clean up of the process table slot. This cancels
* outstanding timers, possibly removes the process from the message queues,
* and resets important process table fields.
*/
clear_proc(exit_proc_nr);
return(OK); /* tell PM that cleanup succeeded */
/* The PM or some other system process requested to be exited. */
clear_proc(m_ptr->m_source);
return(EDONTREPLY);
}

View file

@ -33,11 +33,11 @@ message *m_ptr; /* pointer to request message */
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
if (rp->p_flags & PENDING) {
if (rp->p_flags & SIGNALED) {
m_ptr->SIG_PROC = rp->p_nr;
m_ptr->SIG_MAP = rp->p_pending;
sigemptyset(&rp->p_pending); /* ball is in PM's court */
rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */
rp->p_flags &= ~SIGNALED; /* blocked by SIG_PENDING */
return(OK);
}
}
@ -57,12 +57,12 @@ message *m_ptr; /* pointer to request message */
register struct proc *rp;
rp = proc_addr(m_ptr->SIG_PROC);
if (isemptyp(rp)) return(EINVAL); /* process already dead? */
if (isemptyp(rp)) return(EINVAL); /* process already dead? */
/* PM has finished one kernel signal. Perhaps process is ready now? */
if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
&& (rp->p_flags &= ~SIG_PENDING) == 0)
lock_ready(rp);
if (! (rp->p_flags & SIGNALED)) /* new signal arrived */
if ((rp->p_flags &= ~SIG_PENDING) == 0) /* remove pending flag */
lock_ready(rp); /* ready if no flags */
return(OK);
}

View file

@ -1,14 +1,3 @@
/* The system call implemented in this file:
* m_type: SYS_EXIT
*
* The parameters for this system call are:
* m1_i1: EXIT_STATUS (exit status, 0 if normal exit)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
#include "../kernel.h"
#include "../ipc.h"
#include "../system.h"
@ -16,36 +5,6 @@
#include <sys/svrctl.h>
#include "../sendmask.h"
/*===========================================================================*
* do_exit *
*===========================================================================*/
PUBLIC int do_exit(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_exit. A server or driver wants to exit. This may happen
* on a panic, but also is done when MINIX is shutdown.
*/
int proc_nr = m_ptr->m_source; /* can only exit own process */
if (m_ptr->EXIT_STATUS != 0) {
kprintf("WARNING: system process %d exited with an error.\n", proc_nr );
}
/* Now call the routine to clean up of the process table slot. This cancels
* outstanding timers, possibly removes the process from the message queues,
* and reset important process table fields.
*/
clear_proc(proc_nr);
/* If the shutdown sequence is active, see if it was awaiting the shutdown
* of this system service. If so, directly continue the stop sequence.
*/
if (shutting_down && shutdown_process == proc_addr(proc_nr)) {
stop_sequence(&shutdown_timer);
}
return(EDONTREPLY); /* no reply is sent */
}
/* The system call implemented in this file:
@ -98,7 +57,6 @@ message *m_ptr; /* pointer to request message */
}
case SYSSENDMASK: {
rp->p_call_mask = SYSTEM_CALL_MASK;
rp->p_type = P_SERVER;
rp->p_sendmask = ALLOW_ALL_MASK;
send_mask_allow(proc_addr(USR8139)->p_sendmask, proc_nr);
send_mask_allow(proc_addr(PM_PROC_NR)->p_sendmask, proc_nr);

View file

@ -24,7 +24,6 @@
* Changes:
* Nov 10, 2004 removed controller->driver mappings (Jorrit N. Herder)
* Oct 17, 2004 updated above and tasktab comments (Jorrit N. Herder)
* Aug 18, 2004 included p_type in tasktab (Jorrit N. Herder)
* May 01, 2004 included p_sendmask in tasktab (Jorrit N. Herder)
*/
@ -62,31 +61,32 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
* routine and stack size is also provided.
*/
PUBLIC struct system_image image[] = {
{ IDLE, idle_task, P_IDLE, PPRI_IDLE, IDLE_STACK, EMPTY_CALL_MASK, IDLE_SENDMASK, "IDLE" },
{ CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, SYSTEM_CALL_MASK, CLOCK_SENDMASK, "CLOCK" },
{ SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_CALL_MASK, SYSTEM_SENDMASK, "SYS" },
{ HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK, EMPTY_CALL_MASK, HARDWARE_SENDMASK,"HARDW." },
{ PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PM_SENDMASK, "PM" },
{ FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, FS_SENDMASK, "FS" },
{ IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, SYSTEM_CALL_MASK, IS_SENDMASK, "IS" },
{ TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, SYSTEM_CALL_MASK, TTY_SENDMASK, "TTY" },
{ MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, MEM_SENDMASK, "MEMORY" },
{ IDLE, idle_task, 0, IDLE_Q, IDLE_STACK, EMPTY_CALL_MASK, DENY_ALL_MASK, "IDLE" },
{ CLOCK, clock_task, 0, TASK_Q, CLOCK_STACK, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "CLOCK" },
{ SYSTASK, sys_task, 0, TASK_Q, SYS_STACK, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "SYS" },
{ HARDWARE, 0, 0, TASK_Q, HARDWARE_STACK, EMPTY_CALL_MASK, ALLOW_ALL_MASK,"HARDW." },
{ PM_PROC_NR, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "PM" },
{ FS_PROC_NR, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FS" },
{ SM_PROC_NR, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "SM" },
{ IS_PROC_NR, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "IS" },
{ TTY, 0, 0, 1, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "TTY" },
{ MEMORY, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "MEMORY" },
#if ENABLE_AT_WINI
{ AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, AT_SENDMASK, "AT_WINI" },
{ AT_WINI, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "AT_WINI" },
#endif
#if ENABLE_FLOPPY
{ FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FLOPPY_SENDMASK, "FLOPPY" },
{ FLOPPY, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FLOPPY" },
#endif
#if ENABLE_PRINTER
{ PRINTER, 0, P_DRIVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PRN_SENDMASK, "PRINTER" },
{ PRINTER, 0, 0, 3, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "PRINTER" },
#endif
#if ENABLE_RTL8139
{ USR8139, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, RTL8139_SENDMASK, "RTL8139" },
{ USR8139, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "RTL8139" },
#endif
#if ENABLE_FXP
{ FXP, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FXP_SENDMASK, "FXP" },
{ FXP, 0, 0, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "FXP" },
#endif
{ INIT_PROC_NR, 0, P_USER, PPRI_USER, 0, USER_CALL_MASK, INIT_SENDMASK, "INIT" },
{ INIT_PROC_NR, 0, 0, USER_Q, 0, USER_CALL_MASK, USER_PROC_SENDMASK, "INIT" },
};
/* Verify the size of the system image table at compile time. If the number