From: Jorrit Herder Date: Fri, 24 Jun 2005 16:24:40 +0000 (+0000) Subject: Cleaned up process table structure: removed p_type, p_pendcount. X-Git-Tag: v3.1.0~705 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/man.dnssec-dsfromkey.html?a=commitdiff_plain;h=a408699ce0fe83d0cbaa9b8875dbb450f9a7defb;p=minix.git 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. --- diff --git a/kernel/Makefile b/kernel/Makefile index c8051449f..8d062572d 100755 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -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 - -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 +depend: + cd system && $(MAKE) -$(MAKEFLAGS) $@ + /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c system/*.c > .depend -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 diff --git a/kernel/clock.c b/kernel/clock.c index e722cb118..e7486b66f 100755 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -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 } diff --git a/kernel/exception.c b/kernel/exception.c index 3cac6ab24..d6af1298e 100755 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -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; } diff --git a/kernel/glo.h b/kernel/glo.h index 7e1f08a5c..fd446e578 100755 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -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 */ diff --git a/kernel/main.c b/kernel/main.c index ee9f1460b..0b46fac20 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -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 @@ -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); } diff --git a/kernel/proc.c b/kernel/proc.c index 7bd2c9e64..301d35f90 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -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)); } diff --git a/kernel/proc.h b/kernel/proc.h index 4972e3428..c2b6834d4 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -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 #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 */ diff --git a/kernel/protect.c b/kernel/protect.c index 0d331845f..4b8acead1 100755 --- a/kernel/protect.c +++ b/kernel/protect.c @@ -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); diff --git a/kernel/sendmask.h b/kernel/sendmask.h index 9db966fba..729b522b7 100644 --- a/kernel/sendmask.h +++ b/kernel/sendmask.h @@ -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 */ diff --git a/kernel/start.c b/kernel/start.c index 06ac5fdb4..7ef1c131c 100755 --- a/kernel/start.c +++ b/kernel/start.c @@ -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); diff --git a/kernel/system.c b/kernel/system.c index 1f1e1e902..e5e7b6fe8 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -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, "", 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) diff --git a/kernel/system.h b/kernel/system.h index ba182bcbd..d6339f2c0 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -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) ); diff --git a/kernel/system/Makefile b/kernel/system/Makefile index 51df0d07d..c08169584 100644 --- a/kernel/system/Makefile +++ b/kernel/system/Makefile @@ -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 - -# 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 +depend: + /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend + +# Include generated dependencies. +include .depend diff --git a/kernel/system/debugging.c b/kernel/system/debugging.c index 20b0f3f31..5c15f9162 100644 --- a/kernel/system/debugging.c +++ b/kernel/system/debugging.c @@ -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); } diff --git a/kernel/system/misc.c b/kernel/system/misc.c index 95a67f0a7..8eea9c6b2 100644 --- a/kernel/system/misc.c +++ b/kernel/system/misc.c @@ -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); } diff --git a/kernel/system/proctl.c b/kernel/system/proctl.c index 0bd3fd7b9..e6f4184b6 100644 --- a/kernel/system/proctl.c +++ b/kernel/system/proctl.c @@ -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 */ - 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*/ + /* Only one in group should have SIGNALED, child doesn't inherit tracing. */ + rpc->p_flags |= NO_MAP; /* inhibit process from running */ + 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); - -#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 */ + /* 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 */ + } + } + + /* The PM or some other system process requested to be exited. */ + clear_proc(m_ptr->m_source); + return(EDONTREPLY); } diff --git a/kernel/system/sigctl.c b/kernel/system/sigctl.c index d4b049841..df7094eb9 100644 --- a/kernel/system/sigctl.c +++ b/kernel/system/sigctl.c @@ -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); } diff --git a/kernel/system/sysctl.c b/kernel/system/sysctl.c index 37da42175..4dd97c283 100644 --- a/kernel/system/sysctl.c +++ b/kernel/system/sysctl.c @@ -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 - */ - #include "../kernel.h" #include "../ipc.h" #include "../system.h" @@ -16,36 +5,6 @@ #include #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); diff --git a/kernel/table.c b/kernel/table.c index f038ce34f..3f03c7701 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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